desireeia 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- desireeia-0.0.1/PKG-INFO +56 -0
- desireeia-0.0.1/README.md +46 -0
- desireeia-0.0.1/desireeia/__init__.py +82 -0
- desireeia-0.0.1/desireeia/_native.py +389 -0
- desireeia-0.0.1/desireeia/engine.py +77 -0
- desireeia-0.0.1/desireeia/enums.py +71 -0
- desireeia-0.0.1/desireeia/generation.py +165 -0
- desireeia-0.0.1/desireeia/lib/linux-x64/DesireeIALocaleEngine.so +0 -0
- desireeia-0.0.1/desireeia/lib/win-x64/DesireeIALocaleEngine.dll +0 -0
- desireeia-0.0.1/desireeia/lib/win-x64/cudart64_13.dll +0 -0
- desireeia-0.0.1/desireeia/model.py +566 -0
- desireeia-0.0.1/desireeia/types.py +220 -0
- desireeia-0.0.1/desireeia/vision.py +104 -0
- desireeia-0.0.1/desireeia.egg-info/PKG-INFO +56 -0
- desireeia-0.0.1/desireeia.egg-info/SOURCES.txt +17 -0
- desireeia-0.0.1/desireeia.egg-info/dependency_links.txt +1 -0
- desireeia-0.0.1/desireeia.egg-info/top_level.txt +1 -0
- desireeia-0.0.1/pyproject.toml +27 -0
- desireeia-0.0.1/setup.cfg +4 -0
desireeia-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: desireeia
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Python wrapper for DesireeIA — local LLM inference engine
|
|
5
|
+
Author: Passaro Francesco Paolo
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Keywords: llm,inference,local,gguf,desireeia
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# desireeia
|
|
12
|
+
|
|
13
|
+
Python wrapper for **DesireeIA**, a local LLM inference engine (GGUF
|
|
14
|
+
models, CPU/GPU backends). This package ships a thin ctypes binding over
|
|
15
|
+
the native engine, with prebuilt binaries bundled per-platform so it works
|
|
16
|
+
without a separate native install step.
|
|
17
|
+
|
|
18
|
+
Full documentation, model compatibility notes, and the C++/CLI side of the
|
|
19
|
+
project live in the main repository:
|
|
20
|
+
https://github.com/passaroweb/DesireeIA (see the project README for
|
|
21
|
+
details).
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
pip install desireeia
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Bundled platforms
|
|
30
|
+
|
|
31
|
+
This wheel bundles the native engine for the platforms it was built on.
|
|
32
|
+
Check `desireeia/lib/` in the installed package for the exact list — at
|
|
33
|
+
minimum `win-x64` and `linux-x64` are included. If your platform/arch
|
|
34
|
+
isn't bundled yet, the package will raise a clear error on import rather
|
|
35
|
+
than silently failing.
|
|
36
|
+
|
|
37
|
+
- **Windows**: the engine DLL and its CUDA runtime (`cudart64_13.dll`,
|
|
38
|
+
for GPU acceleration) are bundled. It also needs the **Microsoft
|
|
39
|
+
Visual C++ Redistributable (x64)** on the system — already present on
|
|
40
|
+
most Windows machines (installed by countless other apps, .NET, GPU
|
|
41
|
+
drivers, etc.), but not bundled in this package. If import fails with
|
|
42
|
+
a missing-DLL error, install it from
|
|
43
|
+
https://aka.ms/vs/17/release/vc_redist.x64.exe and retry.
|
|
44
|
+
- **Linux**: the engine `.so` only depends on `libstdc++`, `libgcc_s`
|
|
45
|
+
and `glibc` — present on essentially every distribution by default,
|
|
46
|
+
nothing extra to install. GPU acceleration is not packaged for Linux
|
|
47
|
+
yet (CPU-only); this is a known gap, not a silent limitation.
|
|
48
|
+
- **macOS**: not built yet (`osx-x64`/`osx-arm64` are not bundled) —
|
|
49
|
+
importing on macOS will fail with a clear error until a macOS build is
|
|
50
|
+
produced.
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
See `LICENSE` — proprietary, no modification or unauthorized integration,
|
|
55
|
+
no AI training/ingestion without explicit written consent from the
|
|
56
|
+
author.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# desireeia
|
|
2
|
+
|
|
3
|
+
Python wrapper for **DesireeIA**, a local LLM inference engine (GGUF
|
|
4
|
+
models, CPU/GPU backends). This package ships a thin ctypes binding over
|
|
5
|
+
the native engine, with prebuilt binaries bundled per-platform so it works
|
|
6
|
+
without a separate native install step.
|
|
7
|
+
|
|
8
|
+
Full documentation, model compatibility notes, and the C++/CLI side of the
|
|
9
|
+
project live in the main repository:
|
|
10
|
+
https://github.com/passaroweb/DesireeIA (see the project README for
|
|
11
|
+
details).
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
pip install desireeia
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Bundled platforms
|
|
20
|
+
|
|
21
|
+
This wheel bundles the native engine for the platforms it was built on.
|
|
22
|
+
Check `desireeia/lib/` in the installed package for the exact list — at
|
|
23
|
+
minimum `win-x64` and `linux-x64` are included. If your platform/arch
|
|
24
|
+
isn't bundled yet, the package will raise a clear error on import rather
|
|
25
|
+
than silently failing.
|
|
26
|
+
|
|
27
|
+
- **Windows**: the engine DLL and its CUDA runtime (`cudart64_13.dll`,
|
|
28
|
+
for GPU acceleration) are bundled. It also needs the **Microsoft
|
|
29
|
+
Visual C++ Redistributable (x64)** on the system — already present on
|
|
30
|
+
most Windows machines (installed by countless other apps, .NET, GPU
|
|
31
|
+
drivers, etc.), but not bundled in this package. If import fails with
|
|
32
|
+
a missing-DLL error, install it from
|
|
33
|
+
https://aka.ms/vs/17/release/vc_redist.x64.exe and retry.
|
|
34
|
+
- **Linux**: the engine `.so` only depends on `libstdc++`, `libgcc_s`
|
|
35
|
+
and `glibc` — present on essentially every distribution by default,
|
|
36
|
+
nothing extra to install. GPU acceleration is not packaged for Linux
|
|
37
|
+
yet (CPU-only); this is a known gap, not a silent limitation.
|
|
38
|
+
- **macOS**: not built yet (`osx-x64`/`osx-arm64` are not bundled) —
|
|
39
|
+
importing on macOS will fail with a clear error until a macOS build is
|
|
40
|
+
produced.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
See `LICENSE` — proprietary, no modification or unauthorized integration,
|
|
45
|
+
no AI training/ingestion without explicit written consent from the
|
|
46
|
+
author.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""DesireeIA Python wrapper — public API.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
import desireeia
|
|
6
|
+
|
|
7
|
+
plan = desireeia.build_plan("model.gguf")
|
|
8
|
+
with desireeia.LocalModel.load("model.gguf", plan) as model:
|
|
9
|
+
tokens = model.tokenize("Hello, how are you?")
|
|
10
|
+
for piece in model.chat_stream([("user", "Hello!")]):
|
|
11
|
+
print(piece, end="", flush=True)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .enums import (
|
|
15
|
+
Backend,
|
|
16
|
+
Error,
|
|
17
|
+
InferenceBackend,
|
|
18
|
+
ModelFormat,
|
|
19
|
+
Quantization,
|
|
20
|
+
SsdTierMode,
|
|
21
|
+
SpecialToken,
|
|
22
|
+
StreamType,
|
|
23
|
+
)
|
|
24
|
+
from .types import (
|
|
25
|
+
ExecutionPlan,
|
|
26
|
+
GenerateOptions,
|
|
27
|
+
HardwareProfile,
|
|
28
|
+
SamplingOptions,
|
|
29
|
+
ToolCall,
|
|
30
|
+
ToolDefinition,
|
|
31
|
+
VisionConfig,
|
|
32
|
+
)
|
|
33
|
+
from .engine import (
|
|
34
|
+
build_plan,
|
|
35
|
+
detect_hardware,
|
|
36
|
+
profile_dump,
|
|
37
|
+
profile_reset,
|
|
38
|
+
version,
|
|
39
|
+
)
|
|
40
|
+
from .model import LocalModel
|
|
41
|
+
from .vision import VisionImageWrapper
|
|
42
|
+
from .generation import (
|
|
43
|
+
StopSequenceScanner,
|
|
44
|
+
ToolCalling,
|
|
45
|
+
StructuredOutput,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
__version__ = "0.1.0"
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
# enums
|
|
52
|
+
"Backend",
|
|
53
|
+
"Error",
|
|
54
|
+
"InferenceBackend",
|
|
55
|
+
"ModelFormat",
|
|
56
|
+
"Quantization",
|
|
57
|
+
"SsdTierMode",
|
|
58
|
+
"SpecialToken",
|
|
59
|
+
"StreamType",
|
|
60
|
+
# types
|
|
61
|
+
"ExecutionPlan",
|
|
62
|
+
"GenerateOptions",
|
|
63
|
+
"HardwareProfile",
|
|
64
|
+
"SamplingOptions",
|
|
65
|
+
"ToolCall",
|
|
66
|
+
"ToolDefinition",
|
|
67
|
+
"VisionConfig",
|
|
68
|
+
# engine
|
|
69
|
+
"build_plan",
|
|
70
|
+
"detect_hardware",
|
|
71
|
+
"profile_dump",
|
|
72
|
+
"profile_reset",
|
|
73
|
+
"version",
|
|
74
|
+
# model
|
|
75
|
+
"LocalModel",
|
|
76
|
+
# vision
|
|
77
|
+
"VisionImageWrapper",
|
|
78
|
+
# generation
|
|
79
|
+
"StopSequenceScanner",
|
|
80
|
+
"ToolCalling",
|
|
81
|
+
"StructuredOutput",
|
|
82
|
+
]
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"""ctypes bindings to DesireeIALocaleEngine — the C ABI bridge.
|
|
2
|
+
|
|
3
|
+
Mirrors src/DesireeIA/Native/NativeMethods.cs exactly. Struct field order and
|
|
4
|
+
types MUST stay identical to the C structs in abi.h: this is a sequential
|
|
5
|
+
blit, not a marshalled conversion.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import ctypes
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import threading
|
|
14
|
+
from ctypes import (
|
|
15
|
+
POINTER,
|
|
16
|
+
c_char_p,
|
|
17
|
+
c_int32,
|
|
18
|
+
c_int64,
|
|
19
|
+
c_uint32,
|
|
20
|
+
c_uint64,
|
|
21
|
+
c_float,
|
|
22
|
+
c_void_p,
|
|
23
|
+
CFUNCTYPE,
|
|
24
|
+
Structure,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
# Library loading
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
_LIB_NAMES = {
|
|
32
|
+
"win32": "DesireeIALocaleEngine.dll",
|
|
33
|
+
"darwin": "libDesireeIALocaleEngine.dylib",
|
|
34
|
+
"linux": "libDesireeIALocaleEngine.so",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Python sys.platform -> (fname suffix, arch candidates in priority order).
|
|
38
|
+
# The bundle ships the engine under desireeia/lib/<RID>/ following the same
|
|
39
|
+
# .NET RID convention used by Build/runtimes/<RID>/native/ (win-x64,
|
|
40
|
+
# linux-x64, osx-x64, osx-arm64, ...).
|
|
41
|
+
_RID_BY_BASE = {
|
|
42
|
+
"win": "win-{arch}",
|
|
43
|
+
"osx": "osx-{arch}",
|
|
44
|
+
"linux": "linux-{arch}",
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_ARCH_MAP = {
|
|
48
|
+
"win": {"amd64": "x64", "x86_64": "x64", "arm64": "arm64", "aarch64": "arm64"},
|
|
49
|
+
"osx": {"arm64": "arm64", "aarch64": "arm64", "x86_64": "x64", "amd64": "x64"},
|
|
50
|
+
"linux": {"x86_64": "x64", "amd64": "x64", "aarch64": "arm64", "arm64": "arm64", "armv7l": "arm", "armv8l": "arm64"},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def _candidate_rids() -> list[str]:
|
|
54
|
+
"""The .NET RIDs this machine could match, most specific first."""
|
|
55
|
+
import platform
|
|
56
|
+
sysname = platform.system().lower()
|
|
57
|
+
machine_raw = platform.machine().lower()
|
|
58
|
+
|
|
59
|
+
base = None
|
|
60
|
+
for key in ("win", "osx", "linux", "windows", "darwin"):
|
|
61
|
+
if sysname == key:
|
|
62
|
+
base = {"windows": "win", "darwin": "osx"}.get(key, key)
|
|
63
|
+
break
|
|
64
|
+
if base is None:
|
|
65
|
+
return []
|
|
66
|
+
|
|
67
|
+
arch_map = _ARCH_MAP.get(base, {})
|
|
68
|
+
arch = arch_map.get(machine_raw, "")
|
|
69
|
+
if not arch:
|
|
70
|
+
return []
|
|
71
|
+
return [f"{base}-{arch}"]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _find_lib() -> ctypes.CDLL:
|
|
75
|
+
env = os.environ.get("DESIREEIA_NATIVE_LIB")
|
|
76
|
+
if env:
|
|
77
|
+
if not os.path.isfile(env):
|
|
78
|
+
raise OSError(f"DESIREEIA_NATIVE_LIB points to a missing file: {env}")
|
|
79
|
+
return _load_with_deps(env)
|
|
80
|
+
|
|
81
|
+
name = _LIB_NAMES.get(sys.platform)
|
|
82
|
+
if name is None:
|
|
83
|
+
raise OSError(f"Unsupported platform: {sys.platform}")
|
|
84
|
+
|
|
85
|
+
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
|
86
|
+
search_dirs: list[str] = []
|
|
87
|
+
|
|
88
|
+
# 1. Bundled per-platform library: desireeia/lib/<RID>/<fname>
|
|
89
|
+
for rid in _candidate_rids():
|
|
90
|
+
search_dirs.append(os.path.join(pkg_dir, "lib", rid))
|
|
91
|
+
|
|
92
|
+
# 2. Same directory as this package (development layout)
|
|
93
|
+
search_dirs.append(pkg_dir)
|
|
94
|
+
|
|
95
|
+
# 3. Alongside the Python package root
|
|
96
|
+
search_dirs.append(os.path.dirname(pkg_dir))
|
|
97
|
+
|
|
98
|
+
# 4. Plain ctypes search (system paths, LD_LIBRARY_PATH, PATH, ...)
|
|
99
|
+
try:
|
|
100
|
+
return _load_with_deps(name)
|
|
101
|
+
except OSError:
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
for d in search_dirs:
|
|
105
|
+
candidate = os.path.join(d, name)
|
|
106
|
+
if os.path.isfile(candidate):
|
|
107
|
+
return _load_with_deps(candidate)
|
|
108
|
+
|
|
109
|
+
raise OSError(
|
|
110
|
+
f"Cannot find {name}. Ship it next to the desireeia package, bundle it "
|
|
111
|
+
f"under desireeia/lib/<RID>/ (Build/python.ps1 does this automatically), "
|
|
112
|
+
f"set DESIREEIA_NATIVE_LIB to its path, or add its directory to "
|
|
113
|
+
f"PATH / LD_LIBRARY_PATH."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _load_with_deps(path: str) -> ctypes.CDLL:
|
|
118
|
+
"""Load the engine, making sibling runtime DLLs (MinGW: libstdc++-6.dll
|
|
119
|
+
and friends) discoverable: on Windows the loader does NOT search the
|
|
120
|
+
engine's own directory for its dependencies, so the bundle dir must be
|
|
121
|
+
registered as a DLL search dir first."""
|
|
122
|
+
if sys.platform == "win32":
|
|
123
|
+
dll_dir = os.path.dirname(os.path.abspath(path))
|
|
124
|
+
if dll_dir and os.path.isdir(dll_dir):
|
|
125
|
+
os.add_dll_directory(dll_dir)
|
|
126
|
+
return ctypes.CDLL(path)
|
|
127
|
+
|
|
128
|
+
_lib: ctypes.CDLL | None = None
|
|
129
|
+
_lib_lock = threading.Lock()
|
|
130
|
+
|
|
131
|
+
def get_lib() -> ctypes.CDLL:
|
|
132
|
+
global _lib
|
|
133
|
+
if _lib is not None:
|
|
134
|
+
return _lib
|
|
135
|
+
with _lib_lock:
|
|
136
|
+
if _lib is not None:
|
|
137
|
+
return _lib
|
|
138
|
+
_lib = _find_lib()
|
|
139
|
+
_setup_signatures(_lib)
|
|
140
|
+
return _lib
|
|
141
|
+
|
|
142
|
+
# ---------------------------------------------------------------------------
|
|
143
|
+
# Log callback type
|
|
144
|
+
# ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
LOG_CB = CFUNCTYPE(None, c_int32, c_char_p, c_void_p)
|
|
147
|
+
|
|
148
|
+
# ---------------------------------------------------------------------------
|
|
149
|
+
# C structs (sequential layout, matching abi.h exactly)
|
|
150
|
+
# ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
class HwInfo(Structure):
|
|
153
|
+
_fields_ = [
|
|
154
|
+
("cpu_threads", c_int32),
|
|
155
|
+
("cpu_has_avx", c_int32),
|
|
156
|
+
("cpu_has_avx2", c_int32),
|
|
157
|
+
("cpu_has_avx512", c_int32),
|
|
158
|
+
("cpu_has_neon", c_int32),
|
|
159
|
+
("cuda_device_count", c_int32),
|
|
160
|
+
("cuda_total_mb", c_int32),
|
|
161
|
+
("ram_total_mb", c_uint64),
|
|
162
|
+
("ram_free_mb", c_uint64),
|
|
163
|
+
("has_metal", c_int32),
|
|
164
|
+
("has_vulkan", c_int32),
|
|
165
|
+
("intel_gpu_count", c_int32),
|
|
166
|
+
("axelera_device_count", c_int32),
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
class Plan(Structure):
|
|
170
|
+
_fields_ = [
|
|
171
|
+
("backend", c_int32),
|
|
172
|
+
("format", c_int32),
|
|
173
|
+
("dense_quant", c_int32),
|
|
174
|
+
("expert_quant", c_int32),
|
|
175
|
+
("n_threads", c_int32),
|
|
176
|
+
("ram_budget_mb", c_uint64),
|
|
177
|
+
("expert_cache_count", c_int32),
|
|
178
|
+
("expert_prefetch_enabled", c_int32),
|
|
179
|
+
("kv_compression_enabled", c_int32),
|
|
180
|
+
("expert_pin_enabled", c_int32),
|
|
181
|
+
("expert_prefetch_depth", c_int32),
|
|
182
|
+
("batch_union_enabled", c_int32),
|
|
183
|
+
("dual_ssd_enabled", c_int32),
|
|
184
|
+
("ssd_tier_mode", c_int32),
|
|
185
|
+
("ssd_tier_cache_mb", c_uint64),
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
class Sampling(Structure):
|
|
189
|
+
_fields_ = [
|
|
190
|
+
("temperature", c_float),
|
|
191
|
+
("top_k", c_int32),
|
|
192
|
+
("top_p", c_float),
|
|
193
|
+
("penalty_repeat", c_float),
|
|
194
|
+
("penalty_freq", c_float),
|
|
195
|
+
("penalty_present", c_float),
|
|
196
|
+
("penalty_last_n", c_int32),
|
|
197
|
+
("seed", c_uint32),
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
class VisionImage(Structure):
|
|
201
|
+
_fields_ = [
|
|
202
|
+
("width", c_uint32),
|
|
203
|
+
("height", c_uint32),
|
|
204
|
+
("channels", c_uint32),
|
|
205
|
+
("data", c_void_p),
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
class VisionConfig(Structure):
|
|
209
|
+
_fields_ = [
|
|
210
|
+
("embedding_dim", c_int32),
|
|
211
|
+
("patch_size", c_int32),
|
|
212
|
+
("image_size", c_int32),
|
|
213
|
+
("num_heads", c_int32),
|
|
214
|
+
("num_layers", c_int32),
|
|
215
|
+
("projection_dim", c_int32),
|
|
216
|
+
("has_encoder", c_int32),
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
# Function signatures
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
|
|
223
|
+
def _setup_signatures(lib: ctypes.CDLL) -> None:
|
|
224
|
+
# version
|
|
225
|
+
lib.desireeia_version.argtypes = []
|
|
226
|
+
lib.desireeia_version.restype = c_char_p
|
|
227
|
+
|
|
228
|
+
# logger
|
|
229
|
+
lib.desireeia_set_logger.argtypes = [LOG_CB, c_void_p]
|
|
230
|
+
lib.desireeia_set_logger.restype = c_int32
|
|
231
|
+
|
|
232
|
+
# hardware probe
|
|
233
|
+
lib.desireeia_probe_hw.argtypes = [POINTER(HwInfo)]
|
|
234
|
+
lib.desireeia_probe_hw.restype = c_int32
|
|
235
|
+
|
|
236
|
+
# plan
|
|
237
|
+
lib.desireeia_make_plan.argtypes = [
|
|
238
|
+
POINTER(HwInfo), c_char_p, POINTER(Plan), POINTER(Plan)
|
|
239
|
+
]
|
|
240
|
+
lib.desireeia_make_plan.restype = c_int32
|
|
241
|
+
|
|
242
|
+
# create / destroy
|
|
243
|
+
lib.desireeia_create.argtypes = [
|
|
244
|
+
c_char_p, POINTER(Plan), LOG_CB, c_void_p, POINTER(c_void_p)
|
|
245
|
+
]
|
|
246
|
+
lib.desireeia_create.restype = c_int32
|
|
247
|
+
|
|
248
|
+
lib.desireeia_destroy.argtypes = [c_void_p]
|
|
249
|
+
lib.desireeia_destroy.restype = c_int32
|
|
250
|
+
|
|
251
|
+
# predict / next_token / context_size
|
|
252
|
+
lib.desireeia_predict.argtypes = [
|
|
253
|
+
c_void_p, POINTER(c_int32), c_uint64, POINTER(c_int32)
|
|
254
|
+
]
|
|
255
|
+
lib.desireeia_predict.restype = c_int32
|
|
256
|
+
|
|
257
|
+
lib.desireeia_next_token.argtypes = [c_void_p, POINTER(c_int32)]
|
|
258
|
+
lib.desireeia_next_token.restype = c_int32
|
|
259
|
+
|
|
260
|
+
lib.desireeia_context_size.argtypes = [c_void_p]
|
|
261
|
+
lib.desireeia_context_size.restype = c_uint64
|
|
262
|
+
|
|
263
|
+
# tokenize
|
|
264
|
+
lib.desireeia_tokenize.argtypes = [
|
|
265
|
+
c_void_p, c_char_p, c_int32,
|
|
266
|
+
POINTER(c_int32), c_uint64, POINTER(c_uint64)
|
|
267
|
+
]
|
|
268
|
+
lib.desireeia_tokenize.restype = c_int32
|
|
269
|
+
|
|
270
|
+
# token_piece
|
|
271
|
+
lib.desireeia_token_piece.argtypes = [
|
|
272
|
+
c_void_p, c_int32, POINTER(ctypes.c_char), c_uint64
|
|
273
|
+
]
|
|
274
|
+
lib.desireeia_token_piece.restype = c_int32
|
|
275
|
+
|
|
276
|
+
# special_token_id
|
|
277
|
+
lib.desireeia_special_token_id.argtypes = [
|
|
278
|
+
c_void_p, c_int32, POINTER(c_int32)
|
|
279
|
+
]
|
|
280
|
+
lib.desireeia_special_token_id.restype = c_int32
|
|
281
|
+
|
|
282
|
+
# is_eog_token
|
|
283
|
+
lib.desireeia_is_eog_token.argtypes = [
|
|
284
|
+
c_void_p, c_int32, POINTER(c_int32)
|
|
285
|
+
]
|
|
286
|
+
lib.desireeia_is_eog_token.restype = c_int32
|
|
287
|
+
|
|
288
|
+
# embed
|
|
289
|
+
lib.desireeia_embed.argtypes = [
|
|
290
|
+
c_void_p, POINTER(c_int32), c_uint64,
|
|
291
|
+
POINTER(c_float), c_uint64, POINTER(c_uint64), POINTER(c_uint32)
|
|
292
|
+
]
|
|
293
|
+
lib.desireeia_embed.restype = c_int32
|
|
294
|
+
|
|
295
|
+
# sampling
|
|
296
|
+
lib.desireeia_set_sampling.argtypes = [c_void_p, POINTER(Sampling)]
|
|
297
|
+
lib.desireeia_set_sampling.restype = c_int32
|
|
298
|
+
|
|
299
|
+
lib.desireeia_get_sampling.argtypes = [c_void_p, POINTER(Sampling)]
|
|
300
|
+
lib.desireeia_get_sampling.restype = c_int32
|
|
301
|
+
|
|
302
|
+
# lora
|
|
303
|
+
lib.desireeia_load_lora_adapter.argtypes = [c_void_p, c_char_p, c_float]
|
|
304
|
+
lib.desireeia_load_lora_adapter.restype = c_int32
|
|
305
|
+
|
|
306
|
+
lib.desireeia_clear_lora_adapters.argtypes = [c_void_p]
|
|
307
|
+
lib.desireeia_clear_lora_adapters.restype = c_int32
|
|
308
|
+
|
|
309
|
+
# prerouter
|
|
310
|
+
lib.desireeia_load_prerouter.argtypes = [c_void_p, c_char_p]
|
|
311
|
+
lib.desireeia_load_prerouter.restype = c_int32
|
|
312
|
+
|
|
313
|
+
lib.desireeia_clear_prerouter.argtypes = [c_void_p]
|
|
314
|
+
lib.desireeia_clear_prerouter.restype = c_int32
|
|
315
|
+
|
|
316
|
+
lib.desireeia_set_prerouter_heuristic.argtypes = [c_void_p, c_int32]
|
|
317
|
+
lib.desireeia_set_prerouter_heuristic.restype = c_int32
|
|
318
|
+
|
|
319
|
+
# chat template
|
|
320
|
+
lib.desireeia_apply_chat_template.argtypes = [
|
|
321
|
+
c_void_p,
|
|
322
|
+
POINTER(c_char_p), POINTER(c_char_p), c_uint64, c_int32,
|
|
323
|
+
POINTER(ctypes.c_char), c_uint64, POINTER(c_uint64)
|
|
324
|
+
]
|
|
325
|
+
lib.desireeia_apply_chat_template.restype = c_int32
|
|
326
|
+
|
|
327
|
+
# profiling
|
|
328
|
+
lib.desireeia_profile_dump.argtypes = [
|
|
329
|
+
POINTER(ctypes.c_char), c_uint64
|
|
330
|
+
]
|
|
331
|
+
lib.desireeia_profile_dump.restype = None
|
|
332
|
+
|
|
333
|
+
lib.desireeia_profile_reset.argtypes = []
|
|
334
|
+
lib.desireeia_profile_reset.restype = None
|
|
335
|
+
|
|
336
|
+
# vision: image load/free
|
|
337
|
+
lib.desireeia_load_image.argtypes = [
|
|
338
|
+
c_char_p, c_int32, POINTER(VisionImage)
|
|
339
|
+
]
|
|
340
|
+
lib.desireeia_load_image.restype = c_int32
|
|
341
|
+
|
|
342
|
+
lib.desireeia_free_image.argtypes = [POINTER(VisionImage)]
|
|
343
|
+
lib.desireeia_free_image.restype = None
|
|
344
|
+
|
|
345
|
+
# vision: standalone context
|
|
346
|
+
lib.desireeia_vision_create.argtypes = [c_char_p, LOG_CB, c_void_p]
|
|
347
|
+
lib.desireeia_vision_create.restype = c_void_p
|
|
348
|
+
|
|
349
|
+
lib.desireeia_vision_destroy.argtypes = [c_void_p]
|
|
350
|
+
lib.desireeia_vision_destroy.restype = None
|
|
351
|
+
|
|
352
|
+
lib.desireeia_vision_get_config.argtypes = [
|
|
353
|
+
c_void_p, POINTER(VisionConfig)
|
|
354
|
+
]
|
|
355
|
+
lib.desireeia_vision_get_config.restype = c_int32
|
|
356
|
+
|
|
357
|
+
lib.desireeia_vision_encode.argtypes = [
|
|
358
|
+
c_void_p, POINTER(VisionImage),
|
|
359
|
+
POINTER(c_float), c_uint64, POINTER(c_uint64), POINTER(c_uint32)
|
|
360
|
+
]
|
|
361
|
+
lib.desireeia_vision_encode.restype = c_int32
|
|
362
|
+
|
|
363
|
+
lib.desireeia_vision_preprocess.argtypes = [
|
|
364
|
+
POINTER(VisionImage), c_int32,
|
|
365
|
+
POINTER(c_float), c_uint64, POINTER(c_uint64)
|
|
366
|
+
]
|
|
367
|
+
lib.desireeia_vision_preprocess.restype = c_int32
|
|
368
|
+
|
|
369
|
+
# vision: ctx-based multimodal
|
|
370
|
+
lib.desireeia_has_vision.argtypes = [c_void_p, POINTER(c_int32)]
|
|
371
|
+
lib.desireeia_has_vision.restype = c_int32
|
|
372
|
+
|
|
373
|
+
lib.desireeia_vision_token_count.argtypes = [c_void_p, POINTER(c_int32)]
|
|
374
|
+
lib.desireeia_vision_token_count.restype = c_int32
|
|
375
|
+
|
|
376
|
+
lib.desireeia_vision_image_token.argtypes = [c_void_p, POINTER(c_int32)]
|
|
377
|
+
lib.desireeia_vision_image_token.restype = c_int32
|
|
378
|
+
|
|
379
|
+
lib.desireeia_vision_encode_ctx.argtypes = [
|
|
380
|
+
c_void_p, POINTER(VisionImage),
|
|
381
|
+
POINTER(c_float), c_uint64, POINTER(c_uint64), POINTER(c_uint32)
|
|
382
|
+
]
|
|
383
|
+
lib.desireeia_vision_encode_ctx.restype = c_int32
|
|
384
|
+
|
|
385
|
+
lib.desireeia_predict_image.argtypes = [
|
|
386
|
+
c_void_p, POINTER(c_int32), c_uint64,
|
|
387
|
+
POINTER(c_float), c_uint64, c_int32, POINTER(c_int32)
|
|
388
|
+
]
|
|
389
|
+
lib.desireeia_predict_image.restype = c_int32
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""DesireeIAEngine — static entry point. Mirrors C# DesireeIAEngine.cs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from . import _native as _nat
|
|
8
|
+
from .enums import Error
|
|
9
|
+
from .types import ExecutionPlan, HardwareProfile
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def version() -> str:
|
|
13
|
+
"""Return the native engine version string."""
|
|
14
|
+
return _nat.get_lib().desireeia_version().decode("utf-8")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def detect_hardware() -> HardwareProfile:
|
|
18
|
+
"""Probe the machine and return a HardwareProfile."""
|
|
19
|
+
hw = _nat.HwInfo()
|
|
20
|
+
err = _nat.get_lib().desireeia_probe_hw(hw)
|
|
21
|
+
if err != Error.OK:
|
|
22
|
+
raise RuntimeError(f"Hardware probe failed: {Error(err).name}")
|
|
23
|
+
return HardwareProfile.from_native(hw)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def build_plan(
|
|
27
|
+
model_path: Optional[str] = None,
|
|
28
|
+
overrides: Optional[ExecutionPlan] = None,
|
|
29
|
+
) -> ExecutionPlan:
|
|
30
|
+
"""Let the native engine auto-detect the best plan, optionally with overrides."""
|
|
31
|
+
lib = _nat.get_lib()
|
|
32
|
+
|
|
33
|
+
hw = _nat.HwInfo()
|
|
34
|
+
err = lib.desireeia_probe_hw(hw)
|
|
35
|
+
if err != Error.OK:
|
|
36
|
+
raise RuntimeError(f"Hardware probe failed: {Error(err).name}")
|
|
37
|
+
|
|
38
|
+
# Bug fixed here: this used to construct a blank, all-zero `_nat.Plan()`
|
|
39
|
+
# and never populate it from `overrides` - `overrides.to_native()` was
|
|
40
|
+
# never called, so every field a caller explicitly set (thread_count,
|
|
41
|
+
# kv_compression, batch_union, expert_prefetch, dense_quantization,
|
|
42
|
+
# ...) was silently discarded and replaced by whatever the native
|
|
43
|
+
# auto-detect logic picks for a zeroed field. The C# binding
|
|
44
|
+
# (DesireeIAEngine.cs BuildPlan, `overrides.ToNative()`) always did
|
|
45
|
+
# this correctly; only this Python wrapper had the gap - which is why
|
|
46
|
+
# a server built on this wrapper (desireeiaserver) measured
|
|
47
|
+
# dramatically lower decode throughput than the CLI on the identical
|
|
48
|
+
# model/hardware, despite requesting the same plan.
|
|
49
|
+
override_native = overrides.to_native() if overrides is not None else _nat.Plan()
|
|
50
|
+
override_ptr = _nat.ctypes.pointer(override_native) if overrides is not None else None
|
|
51
|
+
plan_out = _nat.Plan()
|
|
52
|
+
|
|
53
|
+
model_bytes = model_path.encode("utf-8") if model_path else None
|
|
54
|
+
|
|
55
|
+
err = lib.desireeia_make_plan(
|
|
56
|
+
_nat.ctypes.byref(hw),
|
|
57
|
+
model_bytes,
|
|
58
|
+
override_ptr,
|
|
59
|
+
_nat.ctypes.byref(plan_out),
|
|
60
|
+
)
|
|
61
|
+
if err != Error.OK:
|
|
62
|
+
raise RuntimeError(f"Plan build failed: {Error(err).name}")
|
|
63
|
+
|
|
64
|
+
return ExecutionPlan.from_native(plan_out)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def profile_dump() -> str:
|
|
68
|
+
"""Human-readable cumulative matmul profiling counters."""
|
|
69
|
+
buf = ( _nat.ctypes.c_char * 2048 )()
|
|
70
|
+
_nat.get_lib().desireeia_profile_dump(buf, 2048)
|
|
71
|
+
raw = buf.value
|
|
72
|
+
return raw.decode("utf-8", errors="replace")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def profile_reset() -> None:
|
|
76
|
+
"""Zero the process-global profiling counters."""
|
|
77
|
+
_nat.get_lib().desireeia_profile_reset()
|