onw 0.10.5: the compile cache prunes itself after a load; attention graphs in onw blob store
Browse files- CHANGELOG.md +9 -0
- CHANGELOG_en.md +8 -0
- TECHNICAL.md +3 -0
- TECHNICAL_en.md +3 -0
- onw/__init__.py +1 -1
- onw/kvcache.py +26 -4
- onw/runtime.py +46 -4
- pyproject.toml +1 -1
CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@
|
|
| 5 |
日付は日本時間です。各版は Hugging Face の `ryugyosoft/onw` にタグ(`v0.4.2` 以降)付きで残っています。
|
| 6 |
onw ウィンドウは、新しい版があるとこのファイルから変更点を表示します(`## v…` の見出しで区切っています)。
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
## v0.10.4 (2026-09-29)
|
| 9 |
- **Lunar Lake:0.10.3 で NPUW のコンパイルは通るのに読み込みが終わらない(最初の推論でプロセスが落ちる)問題を修正**。
|
| 10 |
NPUW の重みバンクはコンパイル後もモデルの .bin を参照し続けるのに、読み込み後に解放していました。.bin はメモリに
|
|
|
|
| 5 |
日付は日本時間です。各版は Hugging Face の `ryugyosoft/onw` にタグ(`v0.4.2` 以降)付きで残っています。
|
| 6 |
onw ウィンドウは、新しい版があるとこのファイルから変更点を表示します(`## v…` の見出しで区切っています)。
|
| 7 |
|
| 8 |
+
## v0.10.5 (2026-09-29)
|
| 9 |
+
- **コンパイルキャッシュの自動掃除**。モデルを読み込んだあと、その読み込みで使わなかったコンパイル結果(別の経路・
|
| 10 |
+
別のブロックサイズ・以前の版の切り分け方のもの)を `npu_cache` から消します。NPUW を使わない機種では OpenVINO 側の
|
| 11 |
+
キャッシュ(コンパイル確認の子プロセスや旧版が残していた複製)も空にします。手元では Gemma 4 の 32.6 GB → 8.1 GB、
|
| 12 |
+
LFM2-8B の 2.0 GB → 0.9 GB。`ONW_CACHE_PRUNE=0` で止められます。
|
| 13 |
+
- アテンションのグラフも onw 自身の blob 置き場(`npu_cache/onw_blobs/attn_*`)に保存するように(OpenVINO のキャッシュを
|
| 14 |
+
onw のもので占めないため)。コンパイル確認の子プロセスも、onw の blob に書き出すときは OpenVINO のキャッシュに複製を
|
| 15 |
+
残しません。
|
| 16 |
+
|
| 17 |
## v0.10.4 (2026-09-29)
|
| 18 |
- **Lunar Lake:0.10.3 で NPUW のコンパイルは通るのに読み込みが終わらない(最初の推論でプロセスが落ちる)問題を修正**。
|
| 19 |
NPUW の重みバンクはコンパイル後もモデルの .bin を参照し続けるのに、読み込み後に解放していました。.bin はメモリに
|
CHANGELOG_en.md
CHANGED
|
@@ -4,6 +4,14 @@
|
|
| 4 |
|
| 5 |
Dates are JST. Every version is on Hugging Face `ryugyosoft/onw`, tagged from `v0.4.2` on.
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
## v0.10.4 (2026-09-29)
|
| 8 |
- **Lunar Lake: with 0.10.3 the NPUW compile finished but the load never did (the process died at the first
|
| 9 |
inference).** NPUW's weights bank keeps reading the model's .bin after compiling, and onw released it after loading.
|
|
|
|
| 4 |
|
| 5 |
Dates are JST. Every version is on Hugging Face `ryugyosoft/onw`, tagged from `v0.4.2` on.
|
| 6 |
|
| 7 |
+
## v0.10.5 (2026-09-29)
|
| 8 |
+
- **The compile cache cleans itself.** After a model is loaded, the compiled files that load did not use (other
|
| 9 |
+
routes, other block sizes, earlier versions of the splitting) are removed from `npu_cache`; on machines without NPUW
|
| 10 |
+
OpenVINO's own cache (duplicates left by the compile probes and older versions) is emptied too. Here: Gemma 4
|
| 11 |
+
32.6 -> 8.1 GB, LFM2-8B 2.0 -> 0.9 GB. `ONW_CACHE_PRUNE=0` turns it off.
|
| 12 |
+
- The attention graphs go to onw's own blob store as well (`npu_cache/onw_blobs/attn_*`), and a compile probe that
|
| 13 |
+
exports to onw's store no longer leaves a copy in OpenVINO's cache.
|
| 14 |
+
|
| 15 |
## v0.10.4 (2026-09-29)
|
| 16 |
- **Lunar Lake: with 0.10.3 the NPUW compile finished but the load never did (the process died at the first
|
| 17 |
inference).** NPUW's weights bank keeps reading the model's .bin after compiling, and onw released it after loading.
|
TECHNICAL.md
CHANGED
|
@@ -81,6 +81,9 @@ NPU は形の決まったグラフしか扱えませんが、MoE はトークン
|
|
| 81 |
で拒否するので、`NPUW_ONLINE_PIPELINE=REP`(繰り返しブロック。部品の中の Sliding 層を折り畳む)でコンパイルし、
|
| 82 |
だめなら NONE(1 サブグラフ)、通常コンパイルの順に落ちます。LM ヘッドは NONE。NPUW の重みバンクはコンパイル後も
|
| 83 |
モデルの .bin を参照するので、.bin は mmap で持ってモデルと同じ寿命にしています(0.10.4)。
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
## Gated DeltaNet(ハイブリッドモデル)を NPU で動かす
|
| 86 |
|
|
|
|
| 81 |
で拒否するので、`NPUW_ONLINE_PIPELINE=REP`(繰り返しブロック。部品の中の Sliding 層を折り畳む)でコンパイルし、
|
| 82 |
だめなら NONE(1 サブグラフ)、通常コンパイルの順に落ちます。LM ヘッドは NONE。NPUW の重みバンクはコンパイル後も
|
| 83 |
モデルの .bin を参照するので、.bin は mmap で持ってモデルと同じ寿命にしています(0.10.4)。
|
| 84 |
+
読み込みが終わると、その読み込みで取り込まなかった `onw_blobs/seg*` を消し、NPUW を使わない機種では OpenVINO 側の
|
| 85 |
+
キャッシュ(`npu_cache/*.blob`。onw の blob は全部自前の置き場にあるので不要)も空にします(0.10.5、`ONW_CACHE_PRUNE=0`
|
| 86 |
+
で無効)。アテンションのグラフと画像エンコーダーは必要になったときにコンパイルするので、掃除の対象外です。
|
| 87 |
|
| 88 |
## Gated DeltaNet(ハイブリッドモデル)を NPU で動かす
|
| 89 |
|
TECHNICAL_en.md
CHANGED
|
@@ -80,6 +80,9 @@ NPUW's default online partitioner (and REG / COMPUTE / SPATIAL) rejects the spli
|
|
| 80 |
so they compile with `NPUW_ONLINE_PIPELINE=REP` (repeated blocks: the sliding layers inside a part get folded), falling
|
| 81 |
back to NONE (one subgraph) and then a plain compile. The LM head goes NONE. NPUW's weights bank keeps reading the
|
| 82 |
model's .bin after compiling, so the .bin is a file-backed mapping that lives as long as the model (0.10.4).
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
## Gated DeltaNet (hybrid models) on the NPU
|
| 85 |
|
|
|
|
| 80 |
so they compile with `NPUW_ONLINE_PIPELINE=REP` (repeated blocks: the sliding layers inside a part get folded), falling
|
| 81 |
back to NONE (one subgraph) and then a plain compile. The LM head goes NONE. NPUW's weights bank keeps reading the
|
| 82 |
model's .bin after compiling, so the .bin is a file-backed mapping that lives as long as the model (0.10.4).
|
| 83 |
+
After a load, the `onw_blobs/seg*` files it did not import are removed, and on machines without NPUW so is OpenVINO's
|
| 84 |
+
own cache (`npu_cache/*.blob`: every blob onw needs is in its own store there) - 0.10.5, `ONW_CACHE_PRUNE=0` disables
|
| 85 |
+
it. The attention graphs and the vision encoder compile on demand and are left alone.
|
| 86 |
|
| 87 |
## Gated DeltaNet (hybrid models) on the NPU
|
| 88 |
|
onw/__init__.py
CHANGED
|
@@ -2,4 +2,4 @@
|
|
| 2 |
|
| 3 |
A small engine that runs LLMs entirely on the Intel NPU: static segment graphs + host-managed state.
|
| 4 |
"""
|
| 5 |
-
__version__ = "0.10.
|
|
|
|
| 2 |
|
| 3 |
A small engine that runs LLMs entirely on the Intel NPU: static segment graphs + host-managed state.
|
| 4 |
"""
|
| 5 |
+
__version__ = "0.10.5"
|
onw/kvcache.py
CHANGED
|
@@ -11,6 +11,7 @@ Layout (measured fastest on NPU 3720): per block one K tensor [kv, C, D] and one
|
|
| 11 |
INT8 in NPU host memory (bound zero-copy); the per-token scales sit outside the matmuls (K's on the scores, V's on the
|
| 12 |
probabilities), so each head is a plain 2-D matmul against "weights".
|
| 13 |
"""
|
|
|
|
| 14 |
import numpy as np
|
| 15 |
import openvino as ov
|
| 16 |
import openvino.opset13 as ops
|
|
@@ -77,10 +78,11 @@ class _Layer:
|
|
| 77 |
|
| 78 |
|
| 79 |
class PagedKV:
|
| 80 |
-
def __init__(self, core, device, layers, capacity, config=None, bits=8):
|
| 81 |
"""layers: {name: dict(kv, D, Dv, scale, G, owner)} - owner: the layer whose cache it reads (shared KV).
|
| 82 |
-
bits: 8 (INT8 with per-token scales) or 16 (f16, scales of 1).
|
| 83 |
-
|
|
|
|
| 84 |
self.kt = ov.Type.f16 if bits == 16 else ov.Type.i8
|
| 85 |
self.capacity = capacity
|
| 86 |
self.ctx = core.get_default_context(device) if device == "NPU" else None
|
|
@@ -146,7 +148,27 @@ class PagedKV:
|
|
| 146 |
key = (R, C, L.kv, L.D, L.Dv, L.scale, str(self.kt))
|
| 147 |
if key not in self.graphs:
|
| 148 |
m = attention_graph(R, C, L.kv, L.D, L.Dv, L.scale, self.kt)
|
| 149 |
-
self.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
return self.graphs[key]
|
| 151 |
|
| 152 |
def attend(self, name, q, pos, S, n, window=None):
|
|
|
|
| 11 |
INT8 in NPU host memory (bound zero-copy); the per-token scales sit outside the matmuls (K's on the scores, V's on the
|
| 12 |
probabilities), so each head is a plain 2-D matmul against "weights".
|
| 13 |
"""
|
| 14 |
+
import io, os
|
| 15 |
import numpy as np
|
| 16 |
import openvino as ov
|
| 17 |
import openvino.opset13 as ops
|
|
|
|
| 78 |
|
| 79 |
|
| 80 |
class PagedKV:
|
| 81 |
+
def __init__(self, core, device, layers, capacity, config=None, bits=8, blobs=None):
|
| 82 |
"""layers: {name: dict(kv, D, Dv, scale, G, owner)} - owner: the layer whose cache it reads (shared KV).
|
| 83 |
+
bits: 8 (INT8 with per-token scales) or 16 (f16, scales of 1). blobs: (cache dir, machine key) to keep the
|
| 84 |
+
compiled attention graphs in onw's own blob store (npu_cache/onw_blobs/attn_*) instead of OpenVINO's cache."""
|
| 85 |
+
self.core, self.device, self.config, self.blobs = core, device, config or {}, blobs
|
| 86 |
self.kt = ov.Type.f16 if bits == 16 else ov.Type.i8
|
| 87 |
self.capacity = capacity
|
| 88 |
self.ctx = core.get_default_context(device) if device == "NPU" else None
|
|
|
|
| 148 |
key = (R, C, L.kv, L.D, L.Dv, L.scale, str(self.kt))
|
| 149 |
if key not in self.graphs:
|
| 150 |
m = attention_graph(R, C, L.kv, L.D, L.Dv, L.scale, self.kt)
|
| 151 |
+
if self.blobs and self.device == "NPU":
|
| 152 |
+
from .runtime import blob_path, import_blob
|
| 153 |
+
bp = blob_path(self.blobs[0], m.get_friendly_name() + f"_Dv{L.Dv}", [self.blobs[1], *key])
|
| 154 |
+
cfg = {k: v for k, v in self.config.items() if k != "CACHE_DIR"}
|
| 155 |
+
cm = None
|
| 156 |
+
if os.path.exists(bp):
|
| 157 |
+
try:
|
| 158 |
+
cm = import_blob(self.core, bp, self.device, cfg)
|
| 159 |
+
except RuntimeError:
|
| 160 |
+
os.remove(bp)
|
| 161 |
+
if cm is None:
|
| 162 |
+
cm = self.core.compile_model(m, self.device, cfg)
|
| 163 |
+
os.makedirs(os.path.dirname(bp), exist_ok=True)
|
| 164 |
+
buf = io.BytesIO()
|
| 165 |
+
cm.export_model(buf)
|
| 166 |
+
with open(bp + ".tmp", "wb") as f:
|
| 167 |
+
f.write(buf.getbuffer())
|
| 168 |
+
os.replace(bp + ".tmp", bp)
|
| 169 |
+
self.graphs[key] = cm.create_infer_request()
|
| 170 |
+
else:
|
| 171 |
+
self.graphs[key] = self.core.compile_model(m, self.device, self.config).create_infer_request()
|
| 172 |
return self.graphs[key]
|
| 173 |
|
| 174 |
def attend(self, name, q, pos, S, n, window=None):
|
onw/runtime.py
CHANGED
|
@@ -140,6 +140,38 @@ def blob_path(cache_dir, name, parts):
|
|
| 140 |
return os.path.join(cache_dir, "onw_blobs", f"{os.path.splitext(os.path.basename(name))[0]}-{h.hexdigest()[:16]}.blob")
|
| 141 |
|
| 142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
def import_blob(core, path, device, cfg):
|
| 144 |
"""Import a compiled blob we wrote ourselves. Unlike a CACHE_DIR hit - which OpenVINO keeps in memory next to the
|
| 145 |
driver's own copy, so it could be exported again - an imported blob is released once the driver has loaded it:
|
|
@@ -369,10 +401,15 @@ class SegmentedModel:
|
|
| 369 |
print(f"[segments] compiled {sum(len(v) for v in self.segs.values())} in {time.time()-t0:.1f}s", flush=True)
|
| 370 |
self.kv = None
|
| 371 |
if kv_dims:
|
|
|
|
|
|
|
| 372 |
self.kv = PagedKV(core, os.environ.get("ONW_KV_DEVICE", device), kv_dims, self.T,
|
| 373 |
{k: v for k, v in (config or {}).items() if k == "CACHE_DIR"},
|
| 374 |
-
bits=int(os.environ.get("ONW_KV_BITS", "8")))
|
| 375 |
print(f"[kv] paged INT8 cache for {len(kv_dims)} attention layers, up to {self.T} tokens", flush=True)
|
|
|
|
|
|
|
|
|
|
| 376 |
self._inputs = {n for lst in self.segs.values() for _, _, names in lst for n in names}
|
| 377 |
self.state, owner = {}, {}
|
| 378 |
for req, m, names in self.segs[min(self.segs)]:
|
|
@@ -432,6 +469,7 @@ class SegmentedModel:
|
|
| 432 |
if own and os.path.exists(bp):
|
| 433 |
try:
|
| 434 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
|
|
|
| 435 |
tried.set(name, how)
|
| 436 |
return req
|
| 437 |
except RuntimeError as e:
|
|
@@ -441,11 +479,13 @@ class SegmentedModel:
|
|
| 441 |
if (how != known or own) and device == "NPU": # compile out of process first (and, own, export there)
|
| 442 |
tried.set(name, "trying:" + how) # a crash of this process too leaves a mark to skip it next time
|
| 443 |
tried.save()
|
| 444 |
-
#
|
| 445 |
-
|
|
|
|
| 446 |
if r is True and own and os.path.exists(bp):
|
| 447 |
try:
|
| 448 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
|
|
|
| 449 |
if how != known:
|
| 450 |
print(f"[compile] {name}: {how}", flush=True)
|
| 451 |
tried.set(name, how)
|
|
@@ -460,7 +500,7 @@ class SegmentedModel:
|
|
| 460 |
err = RuntimeError(f"{name}: {how}: {r}")
|
| 461 |
continue
|
| 462 |
try:
|
| 463 |
-
req = core.compile_model(model, device, cfg).create_infer_request()
|
| 464 |
if how != known:
|
| 465 |
print(f"[compile] {name}: {how}", flush=True)
|
| 466 |
tried.set(name, how)
|
|
@@ -512,6 +552,7 @@ class SegmentedModel:
|
|
| 512 |
if own and os.path.exists(bp):
|
| 513 |
try:
|
| 514 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
|
|
|
| 515 |
tried.set(pname, how)
|
| 516 |
return req
|
| 517 |
except RuntimeError:
|
|
@@ -526,6 +567,7 @@ class SegmentedModel:
|
|
| 526 |
with open(bp + ".tmp", "wb") as f:
|
| 527 |
f.write(buf.getbuffer())
|
| 528 |
os.replace(bp + ".tmp", bp)
|
|
|
|
| 529 |
if how != known:
|
| 530 |
print(f"[compile] {pname}: {how}", flush=True)
|
| 531 |
tried.set(pname, how)
|
|
|
|
| 140 |
return os.path.join(cache_dir, "onw_blobs", f"{os.path.splitext(os.path.basename(name))[0]}-{h.hexdigest()[:16]}.blob")
|
| 141 |
|
| 142 |
|
| 143 |
+
USED_BLOBS = set() # onw_blobs files this process imported or wrote (see prune_cache)
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def prune_cache(cache_dir, plain_only):
|
| 147 |
+
"""Drop compiled files a load did not use: onw_blobs/seg* not in USED_BLOBS (other routes, other block sizes,
|
| 148 |
+
earlier versions of the splitting), and - when every route is plain, so nothing of ours lives in OpenVINO's own
|
| 149 |
+
cache - the *.blob entries in the cache root (compile probes and older versions left them). Attention graphs and
|
| 150 |
+
the vision encoder (compiled later, on demand) are keyed by the machine and left alone."""
|
| 151 |
+
gone, n, busy = 0, 0, 0
|
| 152 |
+
stale = []
|
| 153 |
+
try:
|
| 154 |
+
blobs = os.path.join(cache_dir, "onw_blobs")
|
| 155 |
+
stale += [os.path.join(blobs, f) for f in os.listdir(blobs) if f.startswith("seg") or f.endswith(".tmp")]
|
| 156 |
+
if plain_only:
|
| 157 |
+
stale += [os.path.join(cache_dir, f) for f in os.listdir(cache_dir) if f.endswith(".blob")]
|
| 158 |
+
except OSError:
|
| 159 |
+
return
|
| 160 |
+
for p in stale:
|
| 161 |
+
if p in USED_BLOBS or not os.path.isfile(p):
|
| 162 |
+
continue
|
| 163 |
+
try:
|
| 164 |
+
size = os.path.getsize(p)
|
| 165 |
+
os.chmod(p, 0o666) # OpenVINO writes its cache entries read-only
|
| 166 |
+
os.remove(p)
|
| 167 |
+
gone, n = gone + size, n + 1
|
| 168 |
+
except OSError: # mapped by another process (a server still running on it)
|
| 169 |
+
busy += 1
|
| 170 |
+
if n or busy:
|
| 171 |
+
print(f"[cache] removed {n} unused compiled files ({gone / 2**30:.1f} GB)"
|
| 172 |
+
+ (f", {busy} in use by another process" if busy else ""), flush=True)
|
| 173 |
+
|
| 174 |
+
|
| 175 |
def import_blob(core, path, device, cfg):
|
| 176 |
"""Import a compiled blob we wrote ourselves. Unlike a CACHE_DIR hit - which OpenVINO keeps in memory next to the
|
| 177 |
driver's own copy, so it could be exported again - an imported blob is released once the driver has loaded it:
|
|
|
|
| 401 |
print(f"[segments] compiled {sum(len(v) for v in self.segs.values())} in {time.time()-t0:.1f}s", flush=True)
|
| 402 |
self.kv = None
|
| 403 |
if kv_dims:
|
| 404 |
+
cache = (config or {}).get("CACHE_DIR")
|
| 405 |
+
own = device == "NPU" and cache and os.environ.get("ONW_OWN_BLOBS") != "0"
|
| 406 |
self.kv = PagedKV(core, os.environ.get("ONW_KV_DEVICE", device), kv_dims, self.T,
|
| 407 |
{k: v for k, v in (config or {}).items() if k == "CACHE_DIR"},
|
| 408 |
+
bits=int(os.environ.get("ONW_KV_BITS", "8")), blobs=(cache, tried.key) if own else None)
|
| 409 |
print(f"[kv] paged INT8 cache for {len(kv_dims)} attention layers, up to {self.T} tokens", flush=True)
|
| 410 |
+
if device == "NPU" and (config or {}).get("CACHE_DIR") and os.environ.get("ONW_CACHE_PRUNE") != "0":
|
| 411 |
+
# everything this load did not touch is stale (or belongs to a route / version no longer taken)
|
| 412 |
+
prune_cache(config["CACHE_DIR"], plain_only=not npuw and os.environ.get("ONW_OWN_BLOBS") != "0")
|
| 413 |
self._inputs = {n for lst in self.segs.values() for _, _, names in lst for n in names}
|
| 414 |
self.state, owner = {}, {}
|
| 415 |
for req, m, names in self.segs[min(self.segs)]:
|
|
|
|
| 469 |
if own and os.path.exists(bp):
|
| 470 |
try:
|
| 471 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
| 472 |
+
USED_BLOBS.add(bp)
|
| 473 |
tried.set(name, how)
|
| 474 |
return req
|
| 475 |
except RuntimeError as e:
|
|
|
|
| 479 |
if (how != known or own) and device == "NPU": # compile out of process first (and, own, export there)
|
| 480 |
tried.set(name, "trying:" + how) # a crash of this process too leaves a mark to skip it next time
|
| 481 |
tried.save()
|
| 482 |
+
# exporting to our store: the child compiles without CACHE_DIR (no second copy in OpenVINO's cache);
|
| 483 |
+
# otherwise it keeps CACHE_DIR and the parent's compile below is a cache hit
|
| 484 |
+
r = _probe(d, name, nocache if own else cfg, npuw, T, export=bp)
|
| 485 |
if r is True and own and os.path.exists(bp):
|
| 486 |
try:
|
| 487 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
| 488 |
+
USED_BLOBS.add(bp)
|
| 489 |
if how != known:
|
| 490 |
print(f"[compile] {name}: {how}", flush=True)
|
| 491 |
tried.set(name, how)
|
|
|
|
| 500 |
err = RuntimeError(f"{name}: {how}: {r}")
|
| 501 |
continue
|
| 502 |
try:
|
| 503 |
+
req = core.compile_model(model, device, nocache if own else cfg).create_infer_request()
|
| 504 |
if how != known:
|
| 505 |
print(f"[compile] {name}: {how}", flush=True)
|
| 506 |
tried.set(name, how)
|
|
|
|
| 552 |
if own and os.path.exists(bp):
|
| 553 |
try:
|
| 554 |
req = import_blob(core, bp, device, nocache).create_infer_request()
|
| 555 |
+
USED_BLOBS.add(bp)
|
| 556 |
tried.set(pname, how)
|
| 557 |
return req
|
| 558 |
except RuntimeError:
|
|
|
|
| 567 |
with open(bp + ".tmp", "wb") as f:
|
| 568 |
f.write(buf.getbuffer())
|
| 569 |
os.replace(bp + ".tmp", bp)
|
| 570 |
+
USED_BLOBS.add(bp)
|
| 571 |
if how != known:
|
| 572 |
print(f"[compile] {pname}: {how}", flush=True)
|
| 573 |
tried.set(pname, how)
|
pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "onw"
|
| 7 |
-
version = "0.10.
|
| 8 |
description = "Ore no NPU ga konna ni ugoku wake nai - LLMs entirely on the Intel NPU"
|
| 9 |
readme = "README.md"
|
| 10 |
license = {text = "Apache-2.0"}
|
|
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "onw"
|
| 7 |
+
version = "0.10.5"
|
| 8 |
description = "Ore no NPU ga konna ni ugoku wake nai - LLMs entirely on the Intel NPU"
|
| 9 |
readme = "README.md"
|
| 10 |
license = {text = "Apache-2.0"}
|