@plasius/gpu-model-runtime 0.1.1 → 0.2.1
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.
- package/README.md +153 -4
- package/dist/index.cjs +873 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +136 -2
- package/dist/index.d.ts +136 -2
- package/dist/index.js +868 -137
- package/dist/index.js.map +1 -1
- package/package.json +17 -10
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# @plasius/gpu-model-runtime
|
|
2
2
|
|
|
3
|
-
Adapter discovery, source resolution, loading orchestration,
|
|
3
|
+
Adapter discovery, source resolution, loading orchestration, bounded residency,
|
|
4
|
+
and worker offload.
|
|
4
5
|
|
|
5
6
|
This repository is the dedicated package boundary defined by ADR 0094.
|
|
6
7
|
|
|
7
|
-
## Bootstrap status
|
|
8
|
-
|
|
9
8
|
The runtime owns orchestration only. Canonical model documents, diagnostics, and
|
|
10
9
|
renderer-specific data remain owned by the corresponding `@plasius/gpu-model-*`
|
|
11
10
|
packages and are carried through generic type parameters until the core package
|
|
@@ -26,7 +25,7 @@ is released.
|
|
|
26
25
|
statuses, abort signals, optional byte ranges, response content types, and
|
|
27
26
|
SHA-256 integrity checks.
|
|
28
27
|
- `MemoryModelCache` keys loaded output by content hash, adapter format, and
|
|
29
|
-
stable adapter options. Call `runtime.invalidate()` to clear all entries or
|
|
28
|
+
stable adapter options and acquisition byte ceiling. Call `runtime.invalidate()` to clear all entries or
|
|
30
29
|
entries for one content hash.
|
|
31
30
|
- Worker execution is opt-in through a `WorkerDispatcher`; consumers that do
|
|
32
31
|
not provide one stay on the main execution path.
|
|
@@ -51,9 +50,148 @@ result.canonicalModel;
|
|
|
51
50
|
result.rendererReady;
|
|
52
51
|
```
|
|
53
52
|
|
|
53
|
+
## Bounded source acquisition
|
|
54
|
+
|
|
55
|
+
Every entrypoint and related resource has a default ceiling of 64 MiB
|
|
56
|
+
(`DEFAULT_MODEL_MAX_BYTES`). `fetchPolicy.maxBytes` applies to URLs, memory,
|
|
57
|
+
Blobs, streams, and injected file reads. Opt into a larger finite positive safe
|
|
58
|
+
integer only after budgeting for that workload:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
await runtime.loadModel(source, {
|
|
62
|
+
fetchPolicy: { maxBytes: 128 * 1024 * 1024, timeoutMs: 30_000 },
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
});
|
|
65
|
+
// In an adapter, tighten the inherited ceiling for one texture:
|
|
66
|
+
await input.resourceResolver.resolve("textures/albedo.png", {
|
|
67
|
+
maxBytes: 8 * 1024 * 1024,
|
|
68
|
+
signal: context.signal,
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
A per-resolution limit can tighten the inherited ceiling, never enlarge it.
|
|
73
|
+
Known lengths are checked before reading/copying, and actual streamed bytes are
|
|
74
|
+
checked before retention even when a server omits/misstates Content-Length or
|
|
75
|
+
ignores Range. `byteLengthHint` can reject an oversized stream early; an
|
|
76
|
+
underestimate never disables actual-byte checks. Hashes still cover the admitted
|
|
77
|
+
bytes, including a returned range. Limits apply to decoded Fetch body bytes;
|
|
78
|
+
compressed Content-Length is only an additional early check.
|
|
79
|
+
|
|
80
|
+
Oversize throws `ModelResourceTooLargeError` with code
|
|
81
|
+
`MODEL_RESOURCE_TOO_LARGE` and a fixed message containing no source identifiers.
|
|
82
|
+
It is not retried. Cancellation and acquisition deadlines stop pending reads,
|
|
83
|
+
cancel/release readers, and request iterator cleanup. An uncooperative producer
|
|
84
|
+
cannot delay the rejection, although its own background work cannot be forcibly
|
|
85
|
+
stopped. File-provider callbacks now receive a third `{ maxBytes }` argument;
|
|
86
|
+
they must enforce it incrementally during their own I/O and honor the signal.
|
|
87
|
+
The runtime checks returned file bytes before hashing or adapter use. Existing
|
|
88
|
+
two-argument providers remain callable but need review for pre-allocation limits.
|
|
89
|
+
|
|
90
|
+
The 30-second default `timeoutMs` now covers local/stream acquisition too;
|
|
91
|
+
for ModelRuntime it includes entrypoint fetching, retries and hashing. Each
|
|
92
|
+
related-resource resolution gets its own deadline and inherits caller abort.
|
|
93
|
+
Direct `fetchResource` retains a deadline per attempt, including retry delay.
|
|
94
|
+
Timeouts must be positive integers no larger than 2,147,483,647 milliseconds.
|
|
95
|
+
|
|
96
|
+
The ceiling is per resource, not a total process/model budget. Stream storage
|
|
97
|
+
grows geometrically with no per-chunk metadata list; live runtime copy storage
|
|
98
|
+
is at most twice the configured ceiling (excluding producer/network buffers and
|
|
99
|
+
hashing). Many tiny/empty chunks yield to the event loop periodically so timers
|
|
100
|
+
can cancel work. Adapters still own total resource count/bytes, decoded image or
|
|
101
|
+
mesh budgets, concurrency and format validation. ModelResidencyManager separately
|
|
102
|
+
bounds resident CPU/GPU resources. Cache identity includes maxBytes so a model
|
|
103
|
+
loaded with a larger ceiling cannot bypass a later stricter request.
|
|
104
|
+
|
|
105
|
+
This behavior requires a **minor release in the current 0.x series**: previously
|
|
106
|
+
accepted resources above 64 MiB require an explicit larger budget. The release
|
|
107
|
+
pipeline allocates the version; consumers must wait for a verified npm release.
|
|
108
|
+
Disabling `gpu.model.conversion.enabled` at the consumer prevents conversion and
|
|
109
|
+
restores its tested fallback. Byte limits remain enforced whenever this runtime
|
|
110
|
+
is called; there is no safety-check bypass flag.
|
|
111
|
+
|
|
112
|
+
The implementation uses browser Web Streams, Blob, AbortController, timers and
|
|
113
|
+
Web Crypto (or injected hashing), with no filesystem dependency. Node 24 tests
|
|
114
|
+
exercise those APIs, streaming/range/integrity semantics and both ESM/CJS builds;
|
|
115
|
+
real-browser integration remains a consumer validation responsibility. See
|
|
116
|
+
[ADR-0008](docs/adrs/adr-0008-bounded-source-acquisition.md).
|
|
117
|
+
|
|
118
|
+
## Model residency
|
|
119
|
+
|
|
120
|
+
`ModelResidencyManager` owns the lifetime of promoted runtime models shared by
|
|
121
|
+
world tiles, zones, editor previews, and other GPU consumers. Cache identity is
|
|
122
|
+
the canonical `ModelAssetRef.contentHash` plus LOD and optional partition ID, so
|
|
123
|
+
many spatial instances can share one adapter load and one GPU resource.
|
|
124
|
+
|
|
125
|
+
The manager provides:
|
|
126
|
+
|
|
127
|
+
- reference-counted, idempotent leases;
|
|
128
|
+
- per-acquisition cancellation without aborting other interested consumers;
|
|
129
|
+
- cancellation of a shared load once every interested consumer has gone away;
|
|
130
|
+
- separate hard CPU/GPU byte budgets and bounded in-flight adapter work;
|
|
131
|
+
- release of timed-out concurrency slots even when an adapter ignores abort;
|
|
132
|
+
- completion of asynchronous eviction disposal before replacement loading;
|
|
133
|
+
- deterministic eviction by lowest retained priority, least-recent use, and
|
|
134
|
+
cache key;
|
|
135
|
+
- exact-once disposal for evicted, failed-integrity, cancelled, timed-out,
|
|
136
|
+
late-completing, and shutdown resources; and
|
|
137
|
+
- immutable accounting metrics for runtime diagnostics.
|
|
138
|
+
|
|
139
|
+
Loaders remain adapter-driven. The package does not eagerly import any model
|
|
140
|
+
format implementation.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { ModelResidencyManager } from "@plasius/gpu-model-runtime";
|
|
144
|
+
|
|
145
|
+
const models = new ModelResidencyManager({
|
|
146
|
+
budget: {
|
|
147
|
+
maxCpuBytes: 256 * 1024 * 1024,
|
|
148
|
+
maxGpuBytes: 384 * 1024 * 1024,
|
|
149
|
+
maxInFlightLoads: 4,
|
|
150
|
+
},
|
|
151
|
+
load: async ({ assetRef, lod, partitionId, signal }) => {
|
|
152
|
+
const loaded = await modelAdapter.load({
|
|
153
|
+
assetRef,
|
|
154
|
+
lod,
|
|
155
|
+
partitionId,
|
|
156
|
+
signal,
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
resource: loaded.resource,
|
|
160
|
+
contentHash: loaded.contentHash,
|
|
161
|
+
cpuBytes: loaded.cpuBytes,
|
|
162
|
+
gpuBytes: loaded.gpuBytes,
|
|
163
|
+
dispose: loaded.dispose,
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const lease = await models.acquire({
|
|
169
|
+
assetRef,
|
|
170
|
+
lod: 0,
|
|
171
|
+
priority: 100,
|
|
172
|
+
estimatedCpuBytes: 4 * 1024 * 1024,
|
|
173
|
+
estimatedGpuBytes: 12 * 1024 * 1024,
|
|
174
|
+
signal,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
render(lease.resource);
|
|
178
|
+
lease.release();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Call `setPriority` and `setPinned` on a live lease as visibility changes. Call
|
|
182
|
+
`shutdown()` when the owning renderer is destroyed; it aborts pending work and
|
|
183
|
+
disposes resident resources without waiting indefinitely for an adapter that
|
|
184
|
+
ignores abort. If detached adapter work eventually completes, its late resource
|
|
185
|
+
is still disposed exactly once.
|
|
186
|
+
|
|
187
|
+
Canonical model identity comes from `@plasius/asset-contracts`; this package
|
|
188
|
+
does not define a parallel asset catalog. See
|
|
189
|
+
[`docs/adrs/adr-0006-content-addressed-model-residency.md`](docs/adrs/adr-0006-content-addressed-model-residency.md).
|
|
190
|
+
|
|
54
191
|
## Rollout
|
|
55
192
|
|
|
56
193
|
- Feature flag: gpu.model.conversion.enabled
|
|
194
|
+
- Origin-shard integration flag: world.persistent-atlas.enabled
|
|
57
195
|
- Capability: none for this package-only layer
|
|
58
196
|
- Rollback: disable the feature flag and keep the published package version pinned to the last validated release
|
|
59
197
|
|
|
@@ -73,3 +211,14 @@ npm pack --dry-run
|
|
|
73
211
|
## License
|
|
74
212
|
|
|
75
213
|
Apache-2.0. See LICENSE, SECURITY.md, and the files under legal/.
|
|
214
|
+
|
|
215
|
+
<!-- BEGIN PLASIUS RELEASE INTEGRITY -->
|
|
216
|
+
## Release integrity
|
|
217
|
+
|
|
218
|
+
CI keeps the administrative contributor registry outside Git and npm package
|
|
219
|
+
artifacts using exact, case-normalised path checks. CI runs on explicit
|
|
220
|
+
GitHub-hosted runners. Publication uses the GitHub-hosted `production` job with
|
|
221
|
+
Node 24 and a pinned npm 11.6.2 client. It is token-free and proceeds only while the prepared SHA
|
|
222
|
+
is the exact `main` head after successful push-triggered CI. Do not dispatch CD
|
|
223
|
+
until the npm trusted-publisher binding is verified.
|
|
224
|
+
<!-- END PLASIUS RELEASE INTEGRITY -->
|