neuratensor 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lib/neuratensor_core.sha256 +1 -0
- lib/neuratensor_core.so +0 -0
- neuratensor/__init__.py +116 -0
- neuratensor/backends.py +228 -0
- neuratensor/cli.py +247 -0
- neuratensor/config.py +224 -0
- neuratensor/demo_sdk_public.py +94 -0
- neuratensor/examples.py +213 -0
- neuratensor/inference.py +322 -0
- neuratensor/model_loader.py +179 -0
- neuratensor/secure_runtime.py +98 -0
- neuratensor/setup.py +61 -0
- neuratensor/tests/__init__.py +6 -0
- neuratensor/tests/test_inference.py +90 -0
- neuratensor/tests/test_model_loader.py +61 -0
- neuratensor-1.0.0.dist-info/LICENSE +17 -0
- neuratensor-1.0.0.dist-info/METADATA +91 -0
- neuratensor-1.0.0.dist-info/RECORD +21 -0
- neuratensor-1.0.0.dist-info/WHEEL +5 -0
- neuratensor-1.0.0.dist-info/entry_points.txt +2 -0
- neuratensor-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a95c77b71fff85e9ebab3d7cb5852628de008e8581564fd2f3b19256225f7908 lib/neuratensor_core.so
|
lib/neuratensor_core.so
ADDED
|
Binary file
|
neuratensor/__init__.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NeuraTensor SDK - Public API
|
|
3
|
+
=============================
|
|
4
|
+
|
|
5
|
+
Production-ready neuromorphic inference SDK with universal hardware support.
|
|
6
|
+
|
|
7
|
+
Public API for NeuraTensor models. The core CUDA kernels are proprietary
|
|
8
|
+
and distributed as compiled binaries.
|
|
9
|
+
|
|
10
|
+
Neuramorphic, Inc. - San Francisco, CA
|
|
11
|
+
Version: 1.0.0
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__version__ = "1.0.0"
|
|
15
|
+
__author__ = "Neuramorphic, Inc."
|
|
16
|
+
__license__ = "Apache 2.0"
|
|
17
|
+
|
|
18
|
+
from .model_loader import ModelLoader
|
|
19
|
+
from .config import SDKConfig, NeuraTensorConfig, ModelSize
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class NeuraTensor:
|
|
23
|
+
"""
|
|
24
|
+
NeuraTensor neuromorphic model (Public API).
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
>>> config = NeuraTensorConfig.preset("64m")
|
|
28
|
+
>>> model = NeuraTensor(config).cuda()
|
|
29
|
+
"""
|
|
30
|
+
def __init__(self, config: NeuraTensorConfig):
|
|
31
|
+
import sys
|
|
32
|
+
import os
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
|
|
35
|
+
# Enable internal imports (SDK is authorized)
|
|
36
|
+
os.environ["NEURATENSOR_INTERNAL"] = "1"
|
|
37
|
+
|
|
38
|
+
# Add neuratensor to path
|
|
39
|
+
sdk_dir = Path(__file__).parent
|
|
40
|
+
neuratensor_dir = sdk_dir.parent
|
|
41
|
+
sys.path.insert(0, str(neuratensor_dir))
|
|
42
|
+
|
|
43
|
+
# Import from core (internal only - SDK authorized)
|
|
44
|
+
from core.model import NeuraTensorModel
|
|
45
|
+
from config.presets import create_64m_config, create_256m_config, create_1b_config
|
|
46
|
+
|
|
47
|
+
# Map SDK config to internal config
|
|
48
|
+
preset_map = {
|
|
49
|
+
"64m": create_64m_config,
|
|
50
|
+
"256m": create_256m_config,
|
|
51
|
+
"1b": create_1b_config,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
model_size = config.model_size.value if hasattr(config.model_size, 'value') else config.model_size
|
|
55
|
+
|
|
56
|
+
if model_size not in preset_map:
|
|
57
|
+
raise ValueError(f"Unknown model size: {model_size}")
|
|
58
|
+
|
|
59
|
+
internal_config = preset_map[model_size]()
|
|
60
|
+
self._model = NeuraTensorModel(internal_config)
|
|
61
|
+
self.config = config
|
|
62
|
+
|
|
63
|
+
# Update SDK config with internal values
|
|
64
|
+
self.config.vocab_size = internal_config.vocab_size
|
|
65
|
+
self.config.hidden_size = internal_config.hidden_size
|
|
66
|
+
|
|
67
|
+
def cuda(self):
|
|
68
|
+
"""Move model to CUDA"""
|
|
69
|
+
self._model = self._model.cuda()
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
def half(self):
|
|
73
|
+
"""Convert model to FP16"""
|
|
74
|
+
self._model = self._model.half()
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def __call__(self, input_ids):
|
|
78
|
+
"""Forward pass"""
|
|
79
|
+
return self._model(input_ids)
|
|
80
|
+
|
|
81
|
+
def count_parameters(self):
|
|
82
|
+
"""Count model parameters"""
|
|
83
|
+
return self._model.count_parameters()
|
|
84
|
+
|
|
85
|
+
__all__ = [
|
|
86
|
+
'NeuraTensor',
|
|
87
|
+
'NeuraTensorConfig',
|
|
88
|
+
'ModelLoader',
|
|
89
|
+
'SDKConfig',
|
|
90
|
+
'ModelSize',
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# Quick start example
|
|
95
|
+
def quick_start():
|
|
96
|
+
"""
|
|
97
|
+
Quick start example for NeuraTensor SDK.
|
|
98
|
+
|
|
99
|
+
Usage:
|
|
100
|
+
>>> from neuratensor.sdk import quick_start
|
|
101
|
+
>>> quick_start()
|
|
102
|
+
"""
|
|
103
|
+
print("=" * 70)
|
|
104
|
+
print("NeuraTensor SDK - Quick Start")
|
|
105
|
+
print("=" * 70)
|
|
106
|
+
print()
|
|
107
|
+
print("from neuratensor.sdk import NeuraTensor")
|
|
108
|
+
print()
|
|
109
|
+
print("# Load model")
|
|
110
|
+
print('model = NeuraTensor.from_pretrained("64m")')
|
|
111
|
+
print()
|
|
112
|
+
print("# Run inference")
|
|
113
|
+
print("output = model(input_ids)")
|
|
114
|
+
print()
|
|
115
|
+
print("# Available models: 64m, 256m, 1b")
|
|
116
|
+
print("=" * 70)
|
neuratensor/backends.py
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hardware Backend Detection
|
|
3
|
+
==========================
|
|
4
|
+
|
|
5
|
+
Auto-detection and management of hardware backends.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import torch
|
|
9
|
+
import platform
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from .config import Backend
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class HardwareBackend:
|
|
15
|
+
"""Base class for hardware backends"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, name: str):
|
|
18
|
+
self.name = name
|
|
19
|
+
self.device_name = None
|
|
20
|
+
self.compute_capability = None
|
|
21
|
+
self.available = False
|
|
22
|
+
|
|
23
|
+
def detect(self) -> bool:
|
|
24
|
+
"""Detect if backend is available"""
|
|
25
|
+
raise NotImplementedError
|
|
26
|
+
|
|
27
|
+
def optimize(self):
|
|
28
|
+
"""Apply backend-specific optimizations"""
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def __repr__(self):
|
|
32
|
+
return f"{self.name}(available={self.available})"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class JetsonOrinBackend(HardwareBackend):
|
|
36
|
+
"""NVIDIA Jetson Orin backend"""
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
super().__init__("jetson_orin")
|
|
40
|
+
|
|
41
|
+
def detect(self) -> bool:
|
|
42
|
+
"""Detect Jetson Orin"""
|
|
43
|
+
if not torch.cuda.is_available():
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
# Check device name
|
|
47
|
+
device_name = torch.cuda.get_device_name(0)
|
|
48
|
+
self.device_name = device_name
|
|
49
|
+
|
|
50
|
+
# Jetson Orin has "Orin" in name and SM 8.7
|
|
51
|
+
if "Orin" in device_name:
|
|
52
|
+
props = torch.cuda.get_device_properties(0)
|
|
53
|
+
self.compute_capability = f"{props.major}.{props.minor}"
|
|
54
|
+
self.available = self.compute_capability == "8.7"
|
|
55
|
+
return self.available
|
|
56
|
+
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
def optimize(self):
|
|
60
|
+
"""Optimize for Jetson Orin"""
|
|
61
|
+
if torch.cuda.is_available():
|
|
62
|
+
# Enable TF32 for Ampere
|
|
63
|
+
torch.backends.cuda.matmul.allow_tf32 = True
|
|
64
|
+
torch.backends.cudnn.allow_tf32 = True
|
|
65
|
+
|
|
66
|
+
# Enable cudnn benchmarking
|
|
67
|
+
torch.backends.cudnn.benchmark = True
|
|
68
|
+
torch.backends.cudnn.deterministic = False
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class JetsonAGXBackend(HardwareBackend):
|
|
72
|
+
"""NVIDIA Jetson AGX Xavier backend"""
|
|
73
|
+
|
|
74
|
+
def __init__(self):
|
|
75
|
+
super().__init__("jetson_agx")
|
|
76
|
+
|
|
77
|
+
def detect(self) -> bool:
|
|
78
|
+
"""Detect Jetson AGX Xavier"""
|
|
79
|
+
if not torch.cuda.is_available():
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
device_name = torch.cuda.get_device_name(0)
|
|
83
|
+
self.device_name = device_name
|
|
84
|
+
|
|
85
|
+
if "Xavier" in device_name:
|
|
86
|
+
props = torch.cuda.get_device_properties(0)
|
|
87
|
+
self.compute_capability = f"{props.major}.{props.minor}"
|
|
88
|
+
self.available = True
|
|
89
|
+
return True
|
|
90
|
+
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class NvidiaDesktopBackend(HardwareBackend):
|
|
95
|
+
"""NVIDIA Desktop GPU backend (RTX, GTX, Tesla)"""
|
|
96
|
+
|
|
97
|
+
def __init__(self):
|
|
98
|
+
super().__init__("nvidia_desktop")
|
|
99
|
+
|
|
100
|
+
def detect(self) -> bool:
|
|
101
|
+
"""Detect desktop NVIDIA GPU"""
|
|
102
|
+
if not torch.cuda.is_available():
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
device_name = torch.cuda.get_device_name(0)
|
|
106
|
+
self.device_name = device_name
|
|
107
|
+
|
|
108
|
+
# Desktop cards
|
|
109
|
+
desktop_keywords = ["RTX", "GTX", "Tesla", "Quadro", "TITAN", "A100", "H100"]
|
|
110
|
+
|
|
111
|
+
for keyword in desktop_keywords:
|
|
112
|
+
if keyword in device_name:
|
|
113
|
+
props = torch.cuda.get_device_properties(0)
|
|
114
|
+
self.compute_capability = f"{props.major}.{props.minor}"
|
|
115
|
+
self.available = True
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
def optimize(self):
|
|
121
|
+
"""Optimize for desktop GPU"""
|
|
122
|
+
if torch.cuda.is_available():
|
|
123
|
+
props = torch.cuda.get_device_properties(0)
|
|
124
|
+
|
|
125
|
+
# Enable TF32 for Ampere and newer (SM >= 8.0)
|
|
126
|
+
if props.major >= 8:
|
|
127
|
+
torch.backends.cuda.matmul.allow_tf32 = True
|
|
128
|
+
torch.backends.cudnn.allow_tf32 = True
|
|
129
|
+
|
|
130
|
+
torch.backends.cudnn.benchmark = True
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class CUDAGenericBackend(HardwareBackend):
|
|
134
|
+
"""Generic CUDA backend (fallback)"""
|
|
135
|
+
|
|
136
|
+
def __init__(self):
|
|
137
|
+
super().__init__("cuda_generic")
|
|
138
|
+
|
|
139
|
+
def detect(self) -> bool:
|
|
140
|
+
"""Detect any CUDA device"""
|
|
141
|
+
if torch.cuda.is_available():
|
|
142
|
+
self.device_name = torch.cuda.get_device_name(0)
|
|
143
|
+
props = torch.cuda.get_device_properties(0)
|
|
144
|
+
self.compute_capability = f"{props.major}.{props.minor}"
|
|
145
|
+
self.available = True
|
|
146
|
+
return True
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def detect_backend() -> HardwareBackend:
|
|
151
|
+
"""
|
|
152
|
+
Auto-detect best available hardware backend.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Detected backend instance
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
>>> backend = detect_backend()
|
|
159
|
+
>>> print(f"Detected: {backend.name}")
|
|
160
|
+
"""
|
|
161
|
+
# Try backends in priority order
|
|
162
|
+
backends = [
|
|
163
|
+
JetsonOrinBackend(),
|
|
164
|
+
JetsonAGXBackend(),
|
|
165
|
+
NvidiaDesktopBackend(),
|
|
166
|
+
CUDAGenericBackend(),
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
for backend in backends:
|
|
170
|
+
if backend.detect():
|
|
171
|
+
return backend
|
|
172
|
+
|
|
173
|
+
# No CUDA available
|
|
174
|
+
generic = HardwareBackend("cpu")
|
|
175
|
+
generic.available = True
|
|
176
|
+
return generic
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def get_backend(backend_type: Backend) -> HardwareBackend:
|
|
180
|
+
"""
|
|
181
|
+
Get specific backend or auto-detect.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
backend_type: Backend enum value
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Backend instance
|
|
188
|
+
"""
|
|
189
|
+
if backend_type == Backend.AUTO:
|
|
190
|
+
return detect_backend()
|
|
191
|
+
|
|
192
|
+
backend_map = {
|
|
193
|
+
Backend.JETSON_ORIN: JetsonOrinBackend(),
|
|
194
|
+
Backend.JETSON_AGX: JetsonAGXBackend(),
|
|
195
|
+
Backend.NVIDIA_DESKTOP: NvidiaDesktopBackend(),
|
|
196
|
+
Backend.CUDA_GENERIC: CUDAGenericBackend(),
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
backend = backend_map.get(backend_type)
|
|
200
|
+
if backend and backend.detect():
|
|
201
|
+
return backend
|
|
202
|
+
|
|
203
|
+
raise RuntimeError(f"Backend {backend_type} not available")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def print_backend_info():
|
|
207
|
+
"""Print information about detected backend"""
|
|
208
|
+
backend = detect_backend()
|
|
209
|
+
|
|
210
|
+
print("=" * 60)
|
|
211
|
+
print("NEURATENSOR BACKEND INFORMATION")
|
|
212
|
+
print("=" * 60)
|
|
213
|
+
print(f"Backend: {backend.name}")
|
|
214
|
+
print(f"Available: {backend.available}")
|
|
215
|
+
|
|
216
|
+
if backend.device_name:
|
|
217
|
+
print(f"Device: {backend.device_name}")
|
|
218
|
+
|
|
219
|
+
if backend.compute_capability:
|
|
220
|
+
print(f"Compute Capability: {backend.compute_capability}")
|
|
221
|
+
|
|
222
|
+
if torch.cuda.is_available():
|
|
223
|
+
print(f"CUDA Version: {torch.version.cuda}")
|
|
224
|
+
print(f"PyTorch Version: {torch.__version__}")
|
|
225
|
+
props = torch.cuda.get_device_properties(0)
|
|
226
|
+
print(f"Total Memory: {props.total_memory / 1024**3:.1f} GB")
|
|
227
|
+
|
|
228
|
+
print("=" * 60)
|
neuratensor/cli.py
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NeuraTensor CLI - Command Line Interface
|
|
3
|
+
=========================================
|
|
4
|
+
|
|
5
|
+
CLI tool for model management and inference.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from . import __version__, NeuraTensor
|
|
13
|
+
from .model_loader import ModelLoader
|
|
14
|
+
from .config import NeuraTensorConfig
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def cmd_info(args):
|
|
18
|
+
"""Display system and model information"""
|
|
19
|
+
print(f"NeuraTensor SDK v{__version__}")
|
|
20
|
+
print("-" * 50)
|
|
21
|
+
|
|
22
|
+
# Import here to avoid loading CUDA if not needed
|
|
23
|
+
import torch
|
|
24
|
+
|
|
25
|
+
print(f"PyTorch: {torch.__version__}")
|
|
26
|
+
print(f"CUDA Available: {torch.cuda.is_available()}")
|
|
27
|
+
|
|
28
|
+
if torch.cuda.is_available():
|
|
29
|
+
print(f"CUDA Version: {torch.version.cuda}")
|
|
30
|
+
print(f"Device Name: {torch.cuda.get_device_name(0)}")
|
|
31
|
+
print(f"Device Count: {torch.cuda.device_count()}")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def cmd_run(args):
|
|
35
|
+
"""Run inference with a model"""
|
|
36
|
+
print(f"Loading model: {args.model}")
|
|
37
|
+
|
|
38
|
+
# Load model
|
|
39
|
+
loader = ModelLoader()
|
|
40
|
+
model = loader.load(args.model, device=args.device)
|
|
41
|
+
|
|
42
|
+
# Create inference engine
|
|
43
|
+
engine = InferenceEngine(model)
|
|
44
|
+
|
|
45
|
+
# Prepare input
|
|
46
|
+
import torch
|
|
47
|
+
if args.input:
|
|
48
|
+
# Load input from file
|
|
49
|
+
input_data = torch.load(args.input)
|
|
50
|
+
else:
|
|
51
|
+
# Generate random input for testing
|
|
52
|
+
config = model.config
|
|
53
|
+
input_data = torch.randint(
|
|
54
|
+
0, config.vocab_size,
|
|
55
|
+
(1, args.seq_length),
|
|
56
|
+
device=args.device
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
print(f"Running inference...")
|
|
60
|
+
result = engine.infer(input_data, return_logits=True)
|
|
61
|
+
|
|
62
|
+
print(f"\nResults:")
|
|
63
|
+
print(f" Latency: {result['latency_ms']:.2f}ms")
|
|
64
|
+
print(f" Output shape: {result['logits'].shape}")
|
|
65
|
+
|
|
66
|
+
if args.output:
|
|
67
|
+
torch.save(result, args.output)
|
|
68
|
+
print(f" Saved to: {args.output}")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def cmd_benchmark(args):
|
|
72
|
+
"""Benchmark model performance"""
|
|
73
|
+
import torch
|
|
74
|
+
import statistics
|
|
75
|
+
|
|
76
|
+
# Header
|
|
77
|
+
print("\n" + "=" * 60)
|
|
78
|
+
print(f"NeuraTensor {args.model.upper()} | Benchmark")
|
|
79
|
+
print("=" * 60)
|
|
80
|
+
|
|
81
|
+
# Device info
|
|
82
|
+
if torch.cuda.is_available():
|
|
83
|
+
device_name = torch.cuda.get_device_name(0)
|
|
84
|
+
compute_cap = torch.cuda.get_device_capability(0)
|
|
85
|
+
print(f"Device: {device_name} (SM {compute_cap[0]}.{compute_cap[1]})")
|
|
86
|
+
print(f"CUDA: {torch.version.cuda}")
|
|
87
|
+
else:
|
|
88
|
+
print("Device: CPU")
|
|
89
|
+
|
|
90
|
+
print("-" * 60)
|
|
91
|
+
|
|
92
|
+
# Load model using public API
|
|
93
|
+
from . import NeuraTensor, NeuraTensorConfig
|
|
94
|
+
|
|
95
|
+
print(f"Loading {args.model} configuration...")
|
|
96
|
+
config = NeuraTensorConfig.preset(args.model)
|
|
97
|
+
model = NeuraTensor(config)
|
|
98
|
+
|
|
99
|
+
if args.device == "cuda" and torch.cuda.is_available():
|
|
100
|
+
model = model.cuda().half()
|
|
101
|
+
print(f"✓ Model loaded on CUDA")
|
|
102
|
+
else:
|
|
103
|
+
print(f"✓ Model loaded on CPU")
|
|
104
|
+
|
|
105
|
+
print(f"✓ Parameters: {model.count_parameters():,}")
|
|
106
|
+
print("-" * 60)
|
|
107
|
+
|
|
108
|
+
# Prepare input
|
|
109
|
+
device = "cuda" if args.device == "cuda" and torch.cuda.is_available() else "cpu"
|
|
110
|
+
input_ids = torch.randint(
|
|
111
|
+
0,
|
|
112
|
+
config.vocab_size,
|
|
113
|
+
(args.batch_size, args.seq_length),
|
|
114
|
+
device=device
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Warmup
|
|
118
|
+
print(f"Warming up ({args.warmup} iterations)...")
|
|
119
|
+
with torch.no_grad():
|
|
120
|
+
for _ in range(args.warmup):
|
|
121
|
+
_ = model(input_ids)
|
|
122
|
+
if device == "cuda":
|
|
123
|
+
torch.cuda.synchronize()
|
|
124
|
+
print("✓ Warmup complete")
|
|
125
|
+
|
|
126
|
+
# Benchmark
|
|
127
|
+
print(f"Benchmarking ({args.iterations} iterations)...")
|
|
128
|
+
latencies = []
|
|
129
|
+
|
|
130
|
+
with torch.no_grad():
|
|
131
|
+
for i in range(args.iterations):
|
|
132
|
+
if device == "cuda":
|
|
133
|
+
torch.cuda.synchronize()
|
|
134
|
+
start = torch.cuda.Event(enable_timing=True)
|
|
135
|
+
end = torch.cuda.Event(enable_timing=True)
|
|
136
|
+
|
|
137
|
+
start.record()
|
|
138
|
+
output = model(input_ids)
|
|
139
|
+
end.record()
|
|
140
|
+
|
|
141
|
+
torch.cuda.synchronize()
|
|
142
|
+
latency_ms = start.elapsed_time(end)
|
|
143
|
+
else:
|
|
144
|
+
import time
|
|
145
|
+
start = time.perf_counter()
|
|
146
|
+
output = model(input_ids)
|
|
147
|
+
end = time.perf_counter()
|
|
148
|
+
latency_ms = (end - start) * 1000
|
|
149
|
+
|
|
150
|
+
latencies.append(latency_ms)
|
|
151
|
+
|
|
152
|
+
if (i + 1) % 10 == 0:
|
|
153
|
+
print(f" Progress: {i + 1}/{args.iterations}")
|
|
154
|
+
|
|
155
|
+
# Calculate statistics
|
|
156
|
+
mean_lat = statistics.mean(latencies)
|
|
157
|
+
std_lat = statistics.stdev(latencies) if len(latencies) > 1 else 0
|
|
158
|
+
min_lat = min(latencies)
|
|
159
|
+
max_lat = max(latencies)
|
|
160
|
+
p99_lat = sorted(latencies)[int(len(latencies) * 0.99)]
|
|
161
|
+
throughput = 1000 / mean_lat * args.batch_size
|
|
162
|
+
|
|
163
|
+
# Results
|
|
164
|
+
print("\n" + "=" * 60)
|
|
165
|
+
print("BENCHMARK RESULTS")
|
|
166
|
+
print("=" * 60)
|
|
167
|
+
print(f"Latency (mean): {mean_lat:.2f} ms ± {std_lat:.2f} ms")
|
|
168
|
+
print(f"Latency (p99): {p99_lat:.2f} ms")
|
|
169
|
+
print(f"Latency (min): {min_lat:.2f} ms")
|
|
170
|
+
print(f"Latency (max): {max_lat:.2f} ms")
|
|
171
|
+
print(f"Throughput: {throughput:.1f} seq/s")
|
|
172
|
+
print(f"Batch size: {args.batch_size}")
|
|
173
|
+
print(f"Sequence length: {args.seq_length}")
|
|
174
|
+
print(f"Kernel: fused_snn_ssm (secure)")
|
|
175
|
+
print("=" * 60)
|
|
176
|
+
print("✓ Benchmark complete")
|
|
177
|
+
print()
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def cmd_list(args):
|
|
181
|
+
"""List available models"""
|
|
182
|
+
loader = ModelLoader()
|
|
183
|
+
models = loader.list_available_models()
|
|
184
|
+
|
|
185
|
+
print("Available Models:")
|
|
186
|
+
print("-" * 50)
|
|
187
|
+
for model_name in models:
|
|
188
|
+
print(f" - {model_name}")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def main():
|
|
192
|
+
"""Main CLI entry point"""
|
|
193
|
+
parser = argparse.ArgumentParser(
|
|
194
|
+
prog="neuratensor",
|
|
195
|
+
description="NeuraTensor SDK - Neuromorphic Tensor Processing"
|
|
196
|
+
)
|
|
197
|
+
parser.add_argument(
|
|
198
|
+
"--version",
|
|
199
|
+
action="version",
|
|
200
|
+
version=f"%(prog)s {__version__}"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
|
204
|
+
|
|
205
|
+
# Info command
|
|
206
|
+
parser_info = subparsers.add_parser("info", help="Display system information")
|
|
207
|
+
parser_info.set_defaults(func=cmd_info)
|
|
208
|
+
|
|
209
|
+
# Run command
|
|
210
|
+
parser_run = subparsers.add_parser("run", help="Run inference")
|
|
211
|
+
parser_run.add_argument("model", help="Model name or path")
|
|
212
|
+
parser_run.add_argument("--input", help="Input file path")
|
|
213
|
+
parser_run.add_argument("--output", help="Output file path")
|
|
214
|
+
parser_run.add_argument("--device", default="cuda", help="Device (cuda/cpu)")
|
|
215
|
+
parser_run.add_argument("--seq-length", type=int, default=64, help="Sequence length")
|
|
216
|
+
parser_run.set_defaults(func=cmd_run)
|
|
217
|
+
|
|
218
|
+
# Benchmark command
|
|
219
|
+
parser_bench = subparsers.add_parser("benchmark", help="Benchmark model")
|
|
220
|
+
parser_bench.add_argument("model", help="Model name or path")
|
|
221
|
+
parser_bench.add_argument("--device", default="cuda", help="Device (cuda/cpu)")
|
|
222
|
+
parser_bench.add_argument("--batch-size", type=int, default=1, help="Batch size")
|
|
223
|
+
parser_bench.add_argument("--seq-length", type=int, default=64, help="Sequence length")
|
|
224
|
+
parser_bench.add_argument("--iterations", type=int, default=30, help="Number of iterations")
|
|
225
|
+
parser_bench.add_argument("--warmup", type=int, default=5, help="Warmup iterations")
|
|
226
|
+
parser_bench.set_defaults(func=cmd_benchmark)
|
|
227
|
+
|
|
228
|
+
# List command
|
|
229
|
+
parser_list = subparsers.add_parser("list", help="List available models")
|
|
230
|
+
parser_list.set_defaults(func=cmd_list)
|
|
231
|
+
|
|
232
|
+
# Parse and execute
|
|
233
|
+
args = parser.parse_args()
|
|
234
|
+
|
|
235
|
+
if not args.command:
|
|
236
|
+
parser.print_help()
|
|
237
|
+
return 1
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
return args.func(args) or 0
|
|
241
|
+
except Exception as e:
|
|
242
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
243
|
+
return 1
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
if __name__ == "__main__":
|
|
247
|
+
sys.exit(main())
|