diff --git a/.changeset/sequence-embeddings-resource-formulas.md b/.changeset/sequence-embeddings-resource-formulas.md
new file mode 100644
index 0000000..8194e94
--- /dev/null
+++ b/.changeset/sequence-embeddings-resource-formulas.md
@@ -0,0 +1,16 @@
+---
+"@platforma-open/milaboratories.sequence-embeddings.software": minor
+"@platforma-open/milaboratories.sequence-embeddings.workflow": patch
+"@platforma-open/milaboratories.sequence-embeddings.model": patch
+"@platforma-open/milaboratories.sequence-embeddings.ui": patch
+"@platforma-open/milaboratories.sequence-embeddings": minor
+---
+
+Optimize embedding compute-resource requests via the fluent `exec.formula` API (workflow-tengo 6.7.x) and size the GPU batch from the allocated VRAM.
+
+- **Workflow** — the embedding exec now declares resources with `.resources({ onCPU | onGPU })` instead of a flat 16 CPU / 32 GiB / 16 GiB-VRAM request:
+ - GPU path: host CPU/RAM cut to 2 cores / 8 GiB (single streaming process; the accelerator does the work, per-chunk CPU work is interleaved, and the heavy PColumn→TSV shaping is already upstream CPU execs), and VRAM is model-tiered — 6 GiB for the wider checkpoints (ESM-2 650M, CurrAb, PeptideCLM-2), 3 GiB otherwise. This fits the cheapest fractional-L4 tiers (gpu-3g `g6f.xlarge` / gpu-6g `g6f.2xlarge`) instead of forcing the 4×L40S `g6e.12xlarge` the old 16 CPU / 32 GiB / 16 GiB-VRAM request required.
+ - CPU path: cores scale with the batch's token volume (`size("batch")`, 4–16) and RAM tracks the core count (2 GiB/core, 8–32 GiB), with a `.staticFallback` equal to the old fixed 16 / 32 GiB for backends that cannot evaluate resource formulas. Advanced-settings overrides still win per dimension.
+ - The run-report counting pass now sizes its RAM from the source-TSV size (it full-loads the TSV), replacing the flat 4 GiB that could OOM on large inputs.
+- **Software** — on CUDA the per-forward token budget is now auto-sized from the allocated VRAM (`PLATFORMA_GPU_MEMORY`), mirroring how `--max-memory-gb` sizes the host-RAM path: a larger VRAM request yields larger batches (higher throughput), a smaller one stays safe. An explicit `--token-budget` still wins, and the halve-on-OOM retry remains the backstop.
+- **Model / UI** — the `mem` / `cpu` Advanced-Settings fields are now opt-in: a new block leaves them unset so the workflow's automatic sizing applies, and a user value overrides it per dimension. (Existing projects keep any value they already had.)
diff --git a/model/src/dataModel.ts b/model/src/dataModel.ts
index 0da420c..81bb754 100644
--- a/model/src/dataModel.ts
+++ b/model/src/dataModel.ts
@@ -53,7 +53,7 @@ export const blockDataModel = new DataModelBuilder()
// The selection is seeded by the UI on first input connection (specialist-first);
// starts blank so the dropdowns have an object to bind to before an input exists.
embedding: {},
- // Resource defaults for the embedding step (Advanced Settings).
- mem: 32,
- cpu: 16,
+ // mem/cpu are intentionally left UNSET: the workflow sizes the embedding step's
+ // resources automatically from device (CPU/GPU) and input volume. They become
+ // opt-in overrides — set only when the user fills them in Advanced Settings.
}));
diff --git a/model/src/types.ts b/model/src/types.ts
index 78e61c8..914d099 100644
--- a/model/src/types.ts
+++ b/model/src/types.ts
@@ -206,8 +206,8 @@ export type BlockDataV1 = {
scopesInitializedForAnchor?: string;
/**
* Advanced — host resources for the embedding step (Resource Allocation in
- * Advanced Settings). `mem` is GiB, `cpu` is cores. Undefined → workflow
- * defaults (32 GiB / 16 cores).
+ * Advanced Settings). `mem` is GiB, `cpu` is cores. Undefined → workflow sizes
+ * automatically from device (CPU/GPU) and input volume.
*/
mem?: number;
cpu?: number;
@@ -227,7 +227,7 @@ export type BlockDataV2 = {
* Init-guard: canonical id of the anchor whose default cards were last seeded.
*/
embeddingsInitializedForAnchor?: string;
- /** Advanced resource overrides (GiB / cores); undefined → workflow defaults. */
+ /** Advanced resource overrides (GiB / cores); undefined → workflow sizes automatically from device + input. */
mem?: number;
cpu?: number;
defaultBlockLabel?: string;
@@ -249,7 +249,7 @@ export type BlockDataV3 = {
* input change.
*/
embeddingInitializedForAnchor?: string;
- /** Advanced resource overrides (GiB / cores); undefined → workflow defaults. */
+ /** Advanced resource overrides (GiB / cores); undefined → workflow sizes automatically from device + input. */
mem?: number;
cpu?: number;
defaultBlockLabel?: string;
@@ -279,7 +279,7 @@ export type BlockArgs = {
inputAnchor: PlRef;
/** Tasks to emit — a 1-element list projected from `data.embedding` (validated complete + compatible). */
embeddings: EmbeddingTask[];
- /** Advanced resource overrides for the embedding step (GiB / cores); undefined → workflow defaults. */
+ /** Advanced resource overrides for the embedding step (GiB / cores); undefined → workflow sizes automatically. */
mem?: number;
cpu?: number;
};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8954d57..a06b761 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -22,26 +22,26 @@ catalogs:
specifier: 1.10.7
version: 1.10.7
'@platforma-sdk/block-tools':
- specifier: 2.11.10
- version: 2.11.10
+ specifier: 2.12.7
+ version: 2.12.7
'@platforma-sdk/model':
- specifier: 1.79.27
- version: 1.79.27
+ specifier: 1.80.2
+ version: 1.80.2
'@platforma-sdk/package-builder':
- specifier: 3.14.0
- version: 3.14.0
+ specifier: 3.14.1
+ version: 3.14.1
'@platforma-sdk/tengo-builder':
- specifier: 4.0.15
- version: 4.0.15
+ specifier: 4.0.18
+ version: 4.0.18
'@platforma-sdk/test':
- specifier: 1.79.28
- version: 1.79.28
+ specifier: 1.80.5
+ version: 1.80.5
'@platforma-sdk/ui-vue':
- specifier: 1.79.27
- version: 1.79.27
+ specifier: 1.80.4
+ version: 1.80.4
'@platforma-sdk/workflow-tengo':
- specifier: 6.6.5
- version: 6.6.5
+ specifier: 6.7.2
+ version: 6.7.2
ag-grid-enterprise:
specifier: ~34.1.2
version: 34.1.2
@@ -83,7 +83,7 @@ importers:
version: 1.6.0(@types/node@25.9.1)(esbuild@0.27.7)(rollup@4.61.0)(vue@3.5.35(typescript@6.0.3))(yaml@2.9.0)
'@platforma-sdk/block-tools':
specifier: 'catalog:'
- version: 2.11.10(@types/node@25.9.1)
+ version: 2.12.7(@types/node@25.9.1)
shx:
specifier: 'catalog:'
version: 0.4.0
@@ -110,10 +110,10 @@ importers:
version: link:../workflow
'@platforma-sdk/block-tools':
specifier: 'catalog:'
- version: 2.11.10(@types/node@25.9.1)
+ version: 2.12.7(@types/node@25.9.1)
'@platforma-sdk/model':
specifier: 'catalog:'
- version: 1.79.27
+ version: 1.80.2
shx:
specifier: 'catalog:'
version: 0.4.0
@@ -125,7 +125,7 @@ importers:
dependencies:
'@platforma-sdk/model':
specifier: 'catalog:'
- version: 1.79.27
+ version: 1.80.2
'@types/node':
specifier: '*'
version: 25.9.1
@@ -141,7 +141,7 @@ importers:
version: 1.3.0
'@platforma-sdk/block-tools':
specifier: 'catalog:'
- version: 2.11.10(@types/node@25.9.1)
+ version: 2.12.7(@types/node@25.9.1)
software:
devDependencies:
@@ -150,7 +150,7 @@ importers:
version: 1.10.7
'@platforma-sdk/package-builder':
specifier: 'catalog:'
- version: 3.14.0
+ version: 3.14.1
test:
dependencies:
@@ -169,7 +169,7 @@ importers:
version: 1.3.0
'@platforma-sdk/test':
specifier: 'catalog:'
- version: 1.79.28(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@7.3.5(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))
+ version: 1.80.5(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@7.3.5(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))
vitest:
specifier: 'catalog:'
version: 4.0.18(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0)
@@ -181,10 +181,10 @@ importers:
version: link:../model
'@platforma-sdk/model':
specifier: 'catalog:'
- version: 1.79.27
+ version: 1.80.2
'@platforma-sdk/ui-vue':
specifier: 'catalog:'
- version: 1.79.27(@bytecodealliance/preview2-shim@0.17.9)(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)
+ version: 1.80.4(@bytecodealliance/preview2-shim@0.17.9)(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)
'@types/node':
specifier: '*'
version: 25.9.1
@@ -218,14 +218,14 @@ importers:
version: link:../software
'@platforma-sdk/workflow-tengo':
specifier: 'catalog:'
- version: 6.6.5
+ version: 6.7.2
devDependencies:
'@platforma-sdk/tengo-builder':
specifier: 'catalog:'
- version: 4.0.15
+ version: 4.0.18
'@platforma-sdk/test':
specifier: 'catalog:'
- version: 1.79.28(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@8.0.16(@types/node@25.9.1)(esbuild@0.27.7)(yaml@2.9.0))
+ version: 1.80.5(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@8.0.16(@types/node@25.9.1)(esbuild@0.27.7)(yaml@2.9.0))
shx:
specifier: 'catalog:'
version: 0.4.0
@@ -313,6 +313,10 @@ packages:
'@aws-crypto/util@5.2.0':
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
+ '@aws-sdk/client-ecr-public@3.859.0':
+ resolution: {integrity: sha512-pPY85lrGBNWynofNC6Er49W6aA4JvOOKC9RDbS8rWR8pBPEG6p0B82VQKFMR+3JYRogpfQf5hzU47um96EslFA==}
+ engines: {node: '>=18.0.0'}
+
'@aws-sdk/client-s3@3.859.0':
resolution: {integrity: sha512-oFLHZX1X6o54ZlweubtSVvQDz15JiNrgDD7KeMZT2MwxiI3axPcHzTo2uizjj5mgNapmYjRmQS5c1c63dvruVA==}
engines: {node: '>=18.0.0'}
@@ -997,95 +1001,98 @@ packages:
'@microsoft/tsdoc@0.16.0':
resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==}
- '@milaboratories/computable@2.9.6':
- resolution: {integrity: sha512-Au+84jboSJMM2k39mWUFCtPl2wkislD1fLbb45du1PcAg1GSER1ThSLoBpZUQC2oiTt804WmbzhZ2yaoVZiVLQ==}
+ '@milaboratories/columns-collection-driver@0.2.1':
+ resolution: {integrity: sha512-CYdDAhmB01jYq0IXJmbMbA/yTfqSkzwRs0ZJxoSvnzvlu1doc63VIXSvhHOw9b70usR5EFVprR2PvPMTRnjeQQ==}
+
+ '@milaboratories/computable@2.9.7':
+ resolution: {integrity: sha512-uCMretdt4okbKWkU0aZ0+NHH3hN0wzi2ZIkAvwqha0ZTxUqKilDOlZNAL6QLbmT/7vQs9geAj4amlwSgzkMoww==}
engines: {node: '>=22.19.0'}
'@milaboratories/helpers@1.14.2':
resolution: {integrity: sha512-zOkD4aWNbembwI+AsPTz7nmWC1VPA4rwGBc+Nd5jPpKVh7rCtZwQrlOP5mVqRVMKIAjb1nU8kzzCGfqNPqfJjA==}
engines: {node: '>=22'}
- '@milaboratories/helpers@1.14.3':
- resolution: {integrity: sha512-nZv+n+orVzA/GimDTNj6Yjb52+Wu5f/Kf2z6UCGXni6KTquLBfQhi3AFB1mLE7hkUYPvKU6LxuRY02CQMQiTVA==}
+ '@milaboratories/helpers@1.14.4':
+ resolution: {integrity: sha512-0mS5GQAQYUab0qj1C6+IXafNJhL1ahnhPBmIkLq9VqJU8p9jNZ7KC5ln4/pl0tK47brdPljCLEiLg8IdSa6wFw==}
engines: {node: '>=22'}
- '@milaboratories/pf-driver@1.7.16':
- resolution: {integrity: sha512-yujIUylT11CwM4alKVETxTnXQpcKHH1x5hZIAKTni/Q98JHs+teewNhUwpaWACwjuEhmF3EYSTgTXeUoeI9hAg==}
+ '@milaboratories/pf-driver@1.8.2':
+ resolution: {integrity: sha512-K5jKzqFfsOJL051U1VAg2Iy9iE01Hwm+FtRb2/PcB0DV3VItIozXRF/mvcXKDHbSCLcPcRGqZjtEF3kMczd+sA==}
engines: {node: '>=22.19.0'}
- '@milaboratories/pf-spec-driver@1.4.18':
- resolution: {integrity: sha512-lXaoSyGCWUlrYZaoyRIWWT0Hpx9DWODXI7VdraNjYnCofJpYKMdAZW3sfCE9kdVup8ic29vywNPLeTjrVQ24sg==}
+ '@milaboratories/pf-spec-driver@1.4.21':
+ resolution: {integrity: sha512-JuYVQKs4aia8DA8MVqdImu+Ho+uTwwOqIaJ3VVPMpCMo3QAH9jZP+wGlkklSwow4d+27Y8L2RJN/1dcPr56GZw==}
- '@milaboratories/pframes-rs-node@1.1.52':
- resolution: {integrity: sha512-Uu4KsQx0GiKvFASI+Cm0nMCMieUVo35mpz4j8mYUYImr7S+bVDDcHweCWrkLkSeImnOQnYHVo9RycViG6QwUQw==}
+ '@milaboratories/pframes-rs-node@1.1.55':
+ resolution: {integrity: sha512-TbudDPMixADLyVr5UsiXhf+zq7YCJA3osFrzDn7Lr5aeyorCjiXDkVOGKpID7GkkssuVsNpPXtoGdA71Y2tLjQ==}
- '@milaboratories/pframes-rs-serv@1.1.52':
- resolution: {integrity: sha512-yVfcyLztgj5UAffj30se5G4MwxkIOFVWPHY1tZZ8zLhQQzx95R/e1toAqq3FLV7y6kpJovwmLusbefgKw9Ejcg==}
+ '@milaboratories/pframes-rs-serv@1.1.55':
+ resolution: {integrity: sha512-cGByUULBA/JiwyFEBZrVNOEbnbrMPWWHCWLprRKlVWlmDMaRmsVft/tFpnle46BhDZWpoWbaKEZ8NGOtGqDCXw==}
hasBin: true
- '@milaboratories/pframes-rs-wasip2@1.1.52':
- resolution: {integrity: sha512-0rb0We6Q/aqrHJ062dayvLb4RExODZdqfsVWdzeHq23alY5TjJRMWsO9aKQpPnOuUKjAimdjlp+Ldq9TVhbEtg==}
+ '@milaboratories/pframes-rs-wasip2@1.1.55':
+ resolution: {integrity: sha512-mwKTmcDiuN6Id2h+oxKX2W5igFhMxDvRZs4clsxhPTYZASSROrvsSsaoXS81meqfC0phx+BUaRpdrkVQIKSdxQ==}
- '@milaboratories/pframes-rs-wasm@1.1.52':
- resolution: {integrity: sha512-Wn8/LJxcsvWSSpdymdebWrBnmgu9wAbzvOiHCtXz7Aqt1M2T8Xp9a7CprzCYx+EvhSuAuoxbq6naxkPsQrbkvg==}
+ '@milaboratories/pframes-rs-wasm@1.1.55':
+ resolution: {integrity: sha512-kVOL+eAasfeiui5lQ5G92nsSiTNSsOnl1m+4my0tmbR7VTCa15dn1kd5RcXS3/8YO5oEcnGlCUhnu5kKMtweEw==}
peerDependencies:
'@bytecodealliance/preview2-shim': 0.17.9
'@milaboratories/pl-model-common': 1.46.2
'@milaboratories/pl-model-middle-layer': 1.30.7
- '@milaboratories/pl-client@3.13.2':
- resolution: {integrity: sha512-5sx6ehEPfo7q4ojyXgPgQIzn4iPZs7YPvEPctRkwQ6cuK5KzLO059FjzUjsJDh5Si7QbUL/yi5qxCf1h1q4G6g==}
+ '@milaboratories/pl-client@3.14.2':
+ resolution: {integrity: sha512-+0ih1njQn4wvLjGmFKboKFRlWYLrzg7QdRK2aNo8ivTKY16TrsMRCk0GQEt0aPKELnv7QSrsNSjg7e7GSdGMDQ==}
engines: {node: '>=22.19.0'}
- '@milaboratories/pl-config@1.8.3':
- resolution: {integrity: sha512-JPIWG/9q7SL9QSYUhHwF9MCfGbpJyo2KxaO9IE2gEvy+oiGw1oBJvNdthC9V/uW2jHp/Qov9+x7LveHzN+bfeA==}
+ '@milaboratories/pl-config@1.8.4':
+ resolution: {integrity: sha512-eBZCIVhl9jRigyJUPURCxH2f2OrU5aToihSrwmTkCOu2rjr1spe4YGMIh9CxPr8Z1GkfQbez3crJGME1+RZrrg==}
- '@milaboratories/pl-deployments@3.0.10':
- resolution: {integrity: sha512-AEFI5gRH1quEUZPqV4wkYabVevpTRGMJXPILsYGh/In9eSw56aHIl8pHoZP5h8v3J5v//KNU7aP8sYANh8S7rA==}
+ '@milaboratories/pl-deployments@3.0.12':
+ resolution: {integrity: sha512-Oo7MGAwMyC8F5zCZWgs3Q/sET584Ussux8YP6TB+UBfWcNwZVZWbiO/QaRewfjnMfKSJ4Uden7RoQ4hHWvWChA==}
engines: {node: '>=22.19.0'}
- '@milaboratories/pl-drivers@1.16.7':
- resolution: {integrity: sha512-tEPv4pWekRa5W9zCX0jK6G5lxtXq5f3FVupszxGgkfeQ9op1p3qI8WA4nin52yskKmwPht0R69K97S6tOc2aSg==}
+ '@milaboratories/pl-drivers@1.16.10':
+ resolution: {integrity: sha512-5lrewLkmN9Z6dWkRw2kYbsjquHNSHBni8seTI3BsP9xijuv4NzEkvDcJLJsQsuZcuaFtyw77fHAKvNmlYZiJeA==}
engines: {node: '>=22'}
'@milaboratories/pl-error-like@1.12.10':
resolution: {integrity: sha512-iHmnLG5lxJqcymUmEL8onCDGEADk1S/5RNACQ5yfTCNcCkUc+7hYrDHQpFmWXPPGC9sG+NTBxt4wr5m8UsLm2g==}
- '@milaboratories/pl-errors@1.4.28':
- resolution: {integrity: sha512-wK/mbJSvGv1aCBCXR9YWXICjWBbWAzyAIAQgGtg3PAIJyONdSOCmV8VFUTMjatYEL/38k/0rUePP8MeYwSVm/g==}
+ '@milaboratories/pl-errors@1.4.31':
+ resolution: {integrity: sha512-XK4npZNtHksD+IHuzsaf4SXtceqRpwCH/PxZy7zijFqNuW5cdl7be8Parr8T+wQzYaDgHLVSKrYilzC56RNx/Q==}
- '@milaboratories/pl-healthcheck@1.0.2':
- resolution: {integrity: sha512-IBXQOSgJj7T/dw26AXBsR1ZaOpoqxZtSFZVPE2TonT0VaLKH4XqMFa3C+fKV1aECqbI45dBRQl/X70CUdGPWgQ==}
+ '@milaboratories/pl-healthcheck@1.0.3':
+ resolution: {integrity: sha512-krt75tuov2T0TKAsybbSzwHt45JjAQJbnqya0FiRApme913k6DvoowEX2NYLzRChbn+QVbs4ODxJI8lcgFexVg==}
engines: {node: '>=22.19.0'}
'@milaboratories/pl-http@1.2.4':
resolution: {integrity: sha512-QKmhx+WEvJCV9dUy/SBdQk/ApaJ5ewBFgm/b+XPlS10SusAdqUUTGvK5+hq8YSuUMXlHb/dk++UtI5YlDuDl2Q==}
- '@milaboratories/pl-middle-layer@1.65.3':
- resolution: {integrity: sha512-cLUOlwyGSQzh1uEh2g3bLxhIDvikMn6ymUegHDZdcEt8Dvvy9kFZnZLfF8MRVGIEJtL/aIumPepaHSlfagTk/A==}
+ '@milaboratories/pl-middle-layer@1.66.4':
+ resolution: {integrity: sha512-rFyxoWpFNjA5FPU6A5Usf0FyDx+XzFSsDqsPRf3NVuxrk6No6cNGZVUerdpXZJ6qCEsJwdgMBRECyBI5MV5bRw==}
engines: {node: '>=22.19.0'}
- '@milaboratories/pl-model-backend@1.4.13':
- resolution: {integrity: sha512-HGEVDZXh/XUU5sDuBB46pMc1+46elzvrPuKCaowhqpzBPzA4j/DNxuJucJRv/h/oE0Ue3kEQf+6x0506kGDrow==}
+ '@milaboratories/pl-model-backend@1.4.16':
+ resolution: {integrity: sha512-MrJwM3aOzrqr3+GVpS/1Zh/SOH/2tBtoyk/+eE6C7LRjofoip8GIF4be8AgPAM3C+6wTSGrQ5x3CM6A8Ql2HVA==}
'@milaboratories/pl-model-common@1.46.2':
resolution: {integrity: sha512-VEeauisApYScvCS8lnK3zpFJ520xuTAodKJmjR8ulHcMrWMyWMfHEdGb7j5OMD0mM/OwTgmQrrJ5eB7Xd+xoOQ==}
- '@milaboratories/pl-model-common@1.46.4':
- resolution: {integrity: sha512-QArgLyQkf8kHSQquxStyk5Xfnau8S4M2vKEbUVQRRoZCzLU1lcDVXRwGgAzRH5NizeqYNrB/wt0/tShajH+6eA==}
+ '@milaboratories/pl-model-common@1.47.1':
+ resolution: {integrity: sha512-5F9I8JvUPRJ2HEzz5MmTio6JFYnhYoMVHfToh2NyXyOyQgAF6jhOzZBOsrEig9NfCPZBRB7v6UjmIK43dG4o/g==}
- '@milaboratories/pl-model-middle-layer@1.30.11':
- resolution: {integrity: sha512-yFThwVqOTb2gJw/tp4PkZcsKI7yRRJCX3QuA6fIc2+tNxCqyEQmdpLmaIY/nhaziIp9ByBT9MrzWNIQd1T9aww==}
+ '@milaboratories/pl-model-middle-layer@1.30.13':
+ resolution: {integrity: sha512-owQVozyub/6aKgk+yce+9sDK+t0HrpLbnlKJqQjYJahuhoju8j6VMY17AWgvADSDCiI3gnp/Tm/I4Ur6ySs1Cg==}
'@milaboratories/pl-model-middle-layer@1.30.7':
resolution: {integrity: sha512-rs9x3Ron4ujR/UOdEgB8WUB1SvZ8ZAScT1Av/e4or+iiQ/CzhmK9nqtYamHVwKV+JgwIFbXQwxGvIHDVz955dQ==}
- '@milaboratories/pl-tree@1.12.18':
- resolution: {integrity: sha512-2vx0JNFDQklz23JMK8s+34LrhFqY0zDDLTLDCOdWgrlNKbd6mr956fKxmvIBML4++Ngs8Izs45B0PNGwhkEBrw==}
+ '@milaboratories/pl-tree@1.13.1':
+ resolution: {integrity: sha512-NtVVUSF9eJA5v5iUEfGgKl0JbG/EIvy+YCsxzCZ1dXG1S3gCNwt01Nj5PkWW7FkDG1IT0ZfwyeO0mVVz2kIv1Q==}
engines: {node: '>=22.19.0'}
- '@milaboratories/ptabler-expression-js@1.2.33':
- resolution: {integrity: sha512-ThB7tc0nPACE7b8cSoA0+zRVZfZHOCAcFioFDi207G5prgrIc/z2zbInjD0PRnWFHO7xOsfbWCkNRDqCmut6zQ==}
+ '@milaboratories/ptabler-expression-js@1.2.35':
+ resolution: {integrity: sha512-nTVNYgNHuUswPnAe8GFAitbewNVMHaxhAncQ3yMYfGzsGgZupQyGV6K1DHVkzMAwNwVFVLwIbiPMY58en03XWQ==}
'@milaboratories/resolve-helper@1.1.3':
resolution: {integrity: sha512-38/dW/XRZQREOxAOOKtO0lzEWPCP/DH0qhB3q1kYcGoN++5V92/zbVwbYrMDeDcjTyo+D62iIep+sKXeWHa7Uw==}
@@ -1105,12 +1112,12 @@ packages:
'@milaboratories/ts-configs@1.3.0':
resolution: {integrity: sha512-6rZaMOJotG+v6eXoupHgPqxArpNBNl0f7sd5K+kUo1PUhPTe632eLJtEeBbFtwDGNYqL9QUacd4pT5t6oDOf0A==}
- '@milaboratories/ts-helpers@1.8.4':
- resolution: {integrity: sha512-YdOyANkJjFiEZgS3bfbludDo9PWOQZQ8AhGw/rpO5/7bgQ9RIVOOTAtP5/UppANoeUiYhCgJt/xvIZgnQ/PZ0w==}
+ '@milaboratories/ts-helpers@1.8.5':
+ resolution: {integrity: sha512-vZDcIBta7I935VjKk6qGdhpjz2pWXe5CbWv1UUmPrcG8wsunDpWuet8/Gi75N97CpcLDc2LLHd/url9K8ZNpAg==}
engines: {node: '>=22.19.0'}
- '@milaboratories/uikit@2.15.13':
- resolution: {integrity: sha512-IdPV9xuwULSx0zXc006dzfOatJBHJ39TmsBnkdsQ235Jz+c++Klpp8tBvDjeXO10nv0xQiIRTXvDCeXebrRTOg==}
+ '@milaboratories/uikit@2.15.16':
+ resolution: {integrity: sha512-HOl1YsPKHpj3izKAs0hEvVtFE8ZbrOnD5KsAqSHxvipQyfAdOLbfB7ak6XPdPKbgsvH5opfMws7usryR6Nlulw==}
'@napi-rs/wasm-runtime@1.1.6':
resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==}
@@ -1704,14 +1711,14 @@ packages:
'@platforma-open/milaboratories.runenv-python-3@1.10.7':
resolution: {integrity: sha512-Rc6iBMfzMh9/kAC44Rv2sQY5svk8K95ty7SdGdEYMlftZBT2rzboc1LP1UcQtWN3ndU2i4Giu+QbKs0MwjHUWQ==}
- '@platforma-open/milaboratories.software-ptabler.schema@1.15.17':
- resolution: {integrity: sha512-Qf4QpFY8bWVtEeQphWGZ67dUaXYVWSFm/AL1ErzdOYhilnDSon2Cya6K2Fkj0TxEGBLMBxOudF/kmTw728/Pag==}
+ '@platforma-open/milaboratories.software-ptabler.schema@1.15.19':
+ resolution: {integrity: sha512-h/FBLELZT6PJZnWtwvcy8bQrpZ2A6xWSVSjyccqb3QolHSbeuwi5UpUph8UxdDYNmWSCH0zR/zE2hFypgk21xA==}
- '@platforma-open/milaboratories.software-ptabler@2.1.3':
- resolution: {integrity: sha512-4cikdkdJ5WYc0Nw3IoZxzlFNKvG1qCAqSjypq5b18pIK6LBDayzhFcuw5TDd8O3bAFhoHP+3cVTmoO9XUTYMRg==}
+ '@platforma-open/milaboratories.software-ptabler@2.1.6':
+ resolution: {integrity: sha512-LdDU9/z+iejw5F98J8DYVQKsjUGGiyu8rHWCjWCEqOVEP+N9QBcN4ibDgG4Xp/GL+IzKxicAkf2Ae9lHollD6w==}
- '@platforma-open/milaboratories.software-ptexter@1.2.2':
- resolution: {integrity: sha512-I08YpKQ4+esLrfpVra5UJ+bznI9Zzba6OW0rKK407a1EUmanvYMVrCbM9gqnm6CHbv2vQxNGSaO8p1LoBh+9gA==}
+ '@platforma-open/milaboratories.software-ptexter@1.2.3':
+ resolution: {integrity: sha512-5wwzvPko/tjkm6EnirsnjB+MO5mF//tgJplI+jPh3bcSHpEdHF+B9xg+S1owAnekqbimMrFZWqHSVY9ZmIHOjw==}
'@platforma-open/milaboratories.software-small-binaries.hello-world-py@1.0.10':
resolution: {integrity: sha512-16BGRLIrsVW+YIaXwWLX6Nbm80PS5mQJEclHhjNbRrRTLHPaKI4RygZfBC0lLNzvHBiTXU4Qkh1+WmdovkshDg==}
@@ -1731,37 +1738,37 @@ packages:
'@platforma-open/milaboratories.software-small-binaries@2.1.1':
resolution: {integrity: sha512-KN1PR7YgUUfx1dxh/TtcoWpSZbOXbRxXzQuJ505qHuXuE0spYwC7bXnvJsEYbEwRcPMa0foTrjBnPNORE4yr+Q==}
- '@platforma-sdk/block-tools@2.11.10':
- resolution: {integrity: sha512-HpPLzw/HIrkXPJ8fGSrZUwnik11ts4tbL1gidmB2Mw8X3uq3N0SDK4qDeHyMY/sVVXeW6tEnyYciWGCr9f5esg==}
+ '@platforma-sdk/block-tools@2.12.7':
+ resolution: {integrity: sha512-a13K0hcXYf+sgx+07QFjIu2uTeTH5lhHHI1o563kvs9Z5vssU9jn7HFgXgSe6TMjDntERJcGHiGm8nUd4t3FiA==}
hasBin: true
'@platforma-sdk/blocks-deps-updater@2.2.0':
resolution: {integrity: sha512-p9lBxhFXM9WoRsrJO7dfkiXSK+1m63yIn1sKhBO71eMbhrLMyVYHEOeNf3w5OCdbRF5QsNhXzWuiTmFK3zHFsA==}
hasBin: true
- '@platforma-sdk/model@1.79.27':
- resolution: {integrity: sha512-Z5WYpClTZoBtvfGsiDPNlRCxPKtUF04TV3MmL1Kfb6xAb04B5NdiqWMnqw+v78Kue/y9FKTmxrCcX9lwZgYFlw==}
+ '@platforma-sdk/model@1.80.2':
+ resolution: {integrity: sha512-aQGVxjxw7y34U0ZuboIYASodJMZ1yTjXH2y44bCdeTeS/r81YBBmGrF6BQhHHVjIOIhaIlWHRBIhd9AJo42aWQ==}
- '@platforma-sdk/package-builder-lib@1.1.0':
- resolution: {integrity: sha512-h/Hx4Fg+kGnX2sVPWJa48JHbSEofTnaOescTKBP1Py5wl3A68BjqKaI6yybLWSR5Ojp3tHNNlvFSAnoF2QYMMg==}
+ '@platforma-sdk/package-builder-lib@1.2.0':
+ resolution: {integrity: sha512-AtSzaZ39BGlqcyYtpGREDz+YlGCDdSTQJNV/+NkTyUtoq1ECRO+iMqAX1DSSza1WqylnURX8vKVI2owS/cxntA==}
- '@platforma-sdk/package-builder@3.14.0':
- resolution: {integrity: sha512-7bRducsc9NLc1zo0GRfz3RHSTejxFfmFvr21EH8NBndGaCj5KvHt2+0jmQsSI1Sl7ZCaj+zQKWWukRlsi+b/uA==}
+ '@platforma-sdk/package-builder@3.14.1':
+ resolution: {integrity: sha512-slkVlHMxPuSvMTfWarFuG4AQHUdBehascrgf7xFaQwgOLbjegMg7IH4XzNzb5IEANZUQYSmHUDcIulKQGXNgog==}
hasBin: true
- '@platforma-sdk/tengo-builder@4.0.15':
- resolution: {integrity: sha512-qBWtAD1f1ZFFfkN7mvYKaI2qKbvQ9wHVh5edGTaKMFU5GFEu5IA3RP4SJw4ht69WjXAEu51VOvvPFwRX1P4H3g==}
+ '@platforma-sdk/tengo-builder@4.0.18':
+ resolution: {integrity: sha512-nGPB5fE6b9ITFuXVMRakr2MyqsnL4TVE09jZ2X7TCPgb31k4gIhYCT+XU9vBRavBj/U3dt+jSWHkcbX9JvJKYA==}
engines: {node: '>=22'}
hasBin: true
- '@platforma-sdk/test@1.79.28':
- resolution: {integrity: sha512-ae/eZMjyhv/m+xg+KoznDWfzFFSPuBKVxVU7orNge10M167xkhrc5fh9pwRJ+HRf2CnWHuUCLEXyfiH8VOnfmA==}
+ '@platforma-sdk/test@1.80.5':
+ resolution: {integrity: sha512-z3tBrNWIg0+OfUOKpiZWCFflSW17J/Tv7DRWK99IzaaS0+MrIhC6oEFJGXnDlbynhnhSp3E+a4HiwEe+SG/rCg==}
- '@platforma-sdk/ui-vue@1.79.27':
- resolution: {integrity: sha512-L88b8A42n4GRGqMHY4n5o+ROwxPBFSgnwr7axjb1k/zfvKRsawz5urxQ8IEPGQW/41UhxNImIiDmdOD17vHtJQ==}
+ '@platforma-sdk/ui-vue@1.80.4':
+ resolution: {integrity: sha512-DQbuO3fAJ3CQxiJkXMiNuo1Qyd/C92AatOZX90ElLFohXiP3XbJNXNjrIxypzsUc850dKkqbPjKd0JTzD12E9w==}
- '@platforma-sdk/workflow-tengo@6.6.5':
- resolution: {integrity: sha512-BIY0DongPruQ7e2EMYy2b0UtO5ziGcLvr2RWgJ8ki17VKNzW3esm/RBszGHMrTYmXM0Yw7mCSasor4vH560g7A==}
+ '@platforma-sdk/workflow-tengo@6.7.2':
+ resolution: {integrity: sha512-KJ4tBigEDN+EIDy7K2u7PqxBIDrhwvnazJthApGg2N/HPZkinKmq0iMzHC9KZ0IsJVg6uxECIB2d2Acko33tOw==}
'@protobuf-ts/grpc-transport@2.11.1':
resolution: {integrity: sha512-l6wrcFffY+tuNnuyrNCkRM8hDIsAZVLA8Mn7PKdVyYxITosYh60qW663p9kL6TWXYuDCL3oxH8ih3vLKTDyhtg==}
@@ -4978,6 +4985,50 @@ snapshots:
'@smithy/util-utf8': 2.3.0
tslib: 2.8.1
+ '@aws-sdk/client-ecr-public@3.859.0':
+ dependencies:
+ '@aws-crypto/sha256-browser': 5.2.0
+ '@aws-crypto/sha256-js': 5.2.0
+ '@aws-sdk/core': 3.858.0
+ '@aws-sdk/credential-provider-node': 3.859.0
+ '@aws-sdk/middleware-host-header': 3.840.0
+ '@aws-sdk/middleware-logger': 3.840.0
+ '@aws-sdk/middleware-recursion-detection': 3.840.0
+ '@aws-sdk/middleware-user-agent': 3.858.0
+ '@aws-sdk/region-config-resolver': 3.840.0
+ '@aws-sdk/types': 3.840.0
+ '@aws-sdk/util-endpoints': 3.848.0
+ '@aws-sdk/util-user-agent-browser': 3.840.0
+ '@aws-sdk/util-user-agent-node': 3.858.0
+ '@smithy/config-resolver': 4.5.6
+ '@smithy/core': 3.24.6
+ '@smithy/fetch-http-handler': 5.4.6
+ '@smithy/hash-node': 4.3.6
+ '@smithy/invalid-dependency': 4.3.6
+ '@smithy/middleware-content-length': 4.3.6
+ '@smithy/middleware-endpoint': 4.5.6
+ '@smithy/middleware-retry': 4.6.6
+ '@smithy/middleware-serde': 4.3.6
+ '@smithy/middleware-stack': 4.3.6
+ '@smithy/node-config-provider': 4.4.6
+ '@smithy/node-http-handler': 4.7.6
+ '@smithy/protocol-http': 5.4.6
+ '@smithy/smithy-client': 4.13.6
+ '@smithy/types': 4.14.3
+ '@smithy/url-parser': 4.3.6
+ '@smithy/util-base64': 4.4.6
+ '@smithy/util-body-length-browser': 4.3.6
+ '@smithy/util-body-length-node': 4.3.6
+ '@smithy/util-defaults-mode-browser': 4.4.6
+ '@smithy/util-defaults-mode-node': 4.3.6
+ '@smithy/util-endpoints': 3.5.6
+ '@smithy/util-middleware': 4.3.6
+ '@smithy/util-retry': 4.4.6
+ '@smithy/util-utf8': 4.3.6
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - aws-crt
+
'@aws-sdk/client-s3@3.859.0':
dependencies:
'@aws-crypto/sha1-browser': 5.2.0
@@ -6062,25 +6113,30 @@ snapshots:
'@microsoft/tsdoc@0.16.0': {}
- '@milaboratories/computable@2.9.6':
+ '@milaboratories/columns-collection-driver@0.2.1':
+ dependencies:
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pl-model-common': 1.47.1
+
+ '@milaboratories/computable@2.9.7':
dependencies:
'@milaboratories/pl-error-like': 1.12.10
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/ts-helpers': 1.8.5
'@types/node': 24.5.2
utility-types: 3.11.0
'@milaboratories/helpers@1.14.2': {}
- '@milaboratories/helpers@1.14.3': {}
+ '@milaboratories/helpers@1.14.4': {}
- '@milaboratories/pf-driver@1.7.16(@bytecodealliance/preview2-shim@0.17.9)':
+ '@milaboratories/pf-driver@1.8.2(@bytecodealliance/preview2-shim@0.17.9)':
dependencies:
- '@milaboratories/helpers': 1.14.3
- '@milaboratories/pframes-rs-node': 1.1.52
- '@milaboratories/pframes-rs-wasm': 1.1.52(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.46.4)(@milaboratories/pl-model-middle-layer@1.30.11)
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pframes-rs-node': 1.1.55
+ '@milaboratories/pframes-rs-wasm': 1.1.55(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.47.1)(@milaboratories/pl-model-middle-layer@1.30.13)
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
+ '@milaboratories/ts-helpers': 1.8.5
es-toolkit: 1.47.0
lru-cache: 11.5.1
transitivePeerDependencies:
@@ -6088,28 +6144,28 @@ snapshots:
- encoding
- supports-color
- '@milaboratories/pf-spec-driver@1.4.18(@bytecodealliance/preview2-shim@0.17.9)':
+ '@milaboratories/pf-spec-driver@1.4.21(@bytecodealliance/preview2-shim@0.17.9)':
dependencies:
- '@milaboratories/helpers': 1.14.3
- '@milaboratories/pframes-rs-wasm': 1.1.52(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.46.4)(@milaboratories/pl-model-middle-layer@1.30.11)
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pframes-rs-wasm': 1.1.55(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.47.1)(@milaboratories/pl-model-middle-layer@1.30.13)
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
'@noble/hashes': 2.2.0
transitivePeerDependencies:
- '@bytecodealliance/preview2-shim'
- '@milaboratories/pframes-rs-node@1.1.52':
+ '@milaboratories/pframes-rs-node@1.1.55':
dependencies:
'@mapbox/node-pre-gyp': 2.0.3
'@milaboratories/helpers': 1.14.2
- '@milaboratories/pframes-rs-serv': 1.1.52
+ '@milaboratories/pframes-rs-serv': 1.1.55
'@milaboratories/pl-model-common': 1.46.2
ulid: 3.0.2
transitivePeerDependencies:
- encoding
- supports-color
- '@milaboratories/pframes-rs-serv@1.1.52':
+ '@milaboratories/pframes-rs-serv@1.1.55':
dependencies:
'@milaboratories/helpers': 1.14.2
'@milaboratories/pl-model-common': 1.46.2
@@ -6118,21 +6174,21 @@ snapshots:
commander: 14.0.3
selfsigned: 5.5.0
- '@milaboratories/pframes-rs-wasip2@1.1.52': {}
+ '@milaboratories/pframes-rs-wasip2@1.1.55': {}
- '@milaboratories/pframes-rs-wasm@1.1.52(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.46.4)(@milaboratories/pl-model-middle-layer@1.30.11)':
+ '@milaboratories/pframes-rs-wasm@1.1.55(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.47.1)(@milaboratories/pl-model-middle-layer@1.30.13)':
dependencies:
'@bytecodealliance/preview2-shim': 0.17.9
- '@milaboratories/pframes-rs-wasip2': 1.1.52
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
+ '@milaboratories/pframes-rs-wasip2': 1.1.55
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
- '@milaboratories/pl-client@3.13.2':
+ '@milaboratories/pl-client@3.14.2':
dependencies:
'@grpc/grpc-js': 1.13.5
'@milaboratories/pl-http': 1.2.4
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/ts-helpers': 1.8.5
'@protobuf-ts/grpc-transport': 2.11.1(@grpc/grpc-js@1.13.5)
'@protobuf-ts/runtime': 2.11.1
'@protobuf-ts/runtime-rpc': 2.11.1
@@ -6145,19 +6201,19 @@ snapshots:
utility-types: 3.11.0
yaml: 2.9.0
- '@milaboratories/pl-config@1.8.3':
+ '@milaboratories/pl-config@1.8.4':
dependencies:
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/ts-helpers': 1.8.5
upath: 2.0.1
yaml: 2.9.0
- '@milaboratories/pl-deployments@3.0.10':
+ '@milaboratories/pl-deployments@3.0.12':
dependencies:
- '@milaboratories/pl-config': 1.8.3
- '@milaboratories/pl-healthcheck': 1.0.2
+ '@milaboratories/pl-config': 1.8.4
+ '@milaboratories/pl-healthcheck': 1.0.3
'@milaboratories/pl-http': 1.2.4
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/ts-helpers': 1.8.5
decompress: 4.2.1
ssh2: 1.17.0
tar: 7.5.16
@@ -6166,15 +6222,15 @@ snapshots:
yaml: 2.9.0
zod: 3.25.76
- '@milaboratories/pl-drivers@1.16.7':
+ '@milaboratories/pl-drivers@1.16.10':
dependencies:
'@grpc/grpc-js': 1.13.5
- '@milaboratories/computable': 2.9.6
- '@milaboratories/helpers': 1.14.3
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-tree': 1.12.18
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/computable': 2.9.7
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-tree': 1.13.1
+ '@milaboratories/ts-helpers': 1.8.5
'@protobuf-ts/grpc-transport': 2.11.1(@grpc/grpc-js@1.13.5)
'@protobuf-ts/plugin': 2.11.1
'@protobuf-ts/runtime': 2.11.1
@@ -6197,16 +6253,16 @@ snapshots:
json-stringify-safe: 5.0.1
zod: 3.25.76
- '@milaboratories/pl-errors@1.4.28':
+ '@milaboratories/pl-errors@1.4.31':
dependencies:
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/ts-helpers': 1.8.5
zod: 3.25.76
- '@milaboratories/pl-healthcheck@1.0.2':
+ '@milaboratories/pl-healthcheck@1.0.3':
dependencies:
'@grpc/grpc-js': 1.13.5
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/ts-helpers': 1.8.5
'@protobuf-ts/grpc-transport': 2.11.1(@grpc/grpc-js@1.13.5)
'@protobuf-ts/runtime': 2.11.1
'@protobuf-ts/runtime-rpc': 2.11.1
@@ -6215,28 +6271,29 @@ snapshots:
dependencies:
undici: 7.16.0
- '@milaboratories/pl-middle-layer@1.65.3(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)':
- dependencies:
- '@milaboratories/computable': 2.9.6
- '@milaboratories/helpers': 1.14.3
- '@milaboratories/pf-driver': 1.7.16(@bytecodealliance/preview2-shim@0.17.9)
- '@milaboratories/pf-spec-driver': 1.4.18(@bytecodealliance/preview2-shim@0.17.9)
- '@milaboratories/pframes-rs-node': 1.1.52
- '@milaboratories/pframes-rs-wasm': 1.1.52(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.46.4)(@milaboratories/pl-model-middle-layer@1.30.11)
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/pl-deployments': 3.0.10
- '@milaboratories/pl-drivers': 1.16.7
- '@milaboratories/pl-errors': 1.4.28
+ '@milaboratories/pl-middle-layer@1.66.4(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)':
+ dependencies:
+ '@milaboratories/columns-collection-driver': 0.2.1
+ '@milaboratories/computable': 2.9.7
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pf-driver': 1.8.2(@bytecodealliance/preview2-shim@0.17.9)
+ '@milaboratories/pf-spec-driver': 1.4.21(@bytecodealliance/preview2-shim@0.17.9)
+ '@milaboratories/pframes-rs-node': 1.1.55
+ '@milaboratories/pframes-rs-wasm': 1.1.55(@bytecodealliance/preview2-shim@0.17.9)(@milaboratories/pl-model-common@1.47.1)(@milaboratories/pl-model-middle-layer@1.30.13)
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/pl-deployments': 3.0.12
+ '@milaboratories/pl-drivers': 1.16.10
+ '@milaboratories/pl-errors': 1.4.31
'@milaboratories/pl-http': 1.2.4
- '@milaboratories/pl-model-backend': 1.4.13
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
- '@milaboratories/pl-tree': 1.12.18
+ '@milaboratories/pl-model-backend': 1.4.16
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
+ '@milaboratories/pl-tree': 1.13.1
'@milaboratories/resolve-helper': 1.1.3
- '@milaboratories/ts-helpers': 1.8.4
- '@platforma-sdk/block-tools': 2.11.10(@types/node@25.9.1)
- '@platforma-sdk/model': 1.79.27
- '@platforma-sdk/workflow-tengo': 6.6.5
+ '@milaboratories/ts-helpers': 1.8.5
+ '@platforma-sdk/block-tools': 2.12.7(@types/node@25.9.1)
+ '@platforma-sdk/model': 1.80.2
+ '@platforma-sdk/workflow-tengo': 6.7.2
canonicalize: 2.1.0
denque: 2.1.0
es-toolkit: 1.47.0
@@ -6257,9 +6314,9 @@ snapshots:
- react-native-b4a
- supports-color
- '@milaboratories/pl-model-backend@1.4.13':
+ '@milaboratories/pl-model-backend@1.4.16':
dependencies:
- '@milaboratories/pl-client': 3.13.2
+ '@milaboratories/pl-client': 3.14.2
canonicalize: 2.1.0
zod: 3.25.76
@@ -6270,17 +6327,18 @@ snapshots:
canonicalize: 2.1.0
zod: 3.25.76
- '@milaboratories/pl-model-common@1.46.4':
+ '@milaboratories/pl-model-common@1.47.1':
dependencies:
- '@milaboratories/helpers': 1.14.3
+ '@milaboratories/helpers': 1.14.4
'@milaboratories/pl-error-like': 1.12.10
canonicalize: 2.1.0
+ es-toolkit: 1.47.0
zod: 3.25.76
- '@milaboratories/pl-model-middle-layer@1.30.11':
+ '@milaboratories/pl-model-middle-layer@1.30.13':
dependencies:
- '@milaboratories/helpers': 1.14.3
- '@milaboratories/pl-model-common': 1.46.4
+ '@milaboratories/helpers': 1.14.4
+ '@milaboratories/pl-model-common': 1.47.1
es-toolkit: 1.47.0
utility-types: 3.11.0
zod: 3.25.76
@@ -6293,19 +6351,19 @@ snapshots:
utility-types: 3.11.0
zod: 3.25.76
- '@milaboratories/pl-tree@1.12.18':
+ '@milaboratories/pl-tree@1.13.1':
dependencies:
- '@milaboratories/computable': 2.9.6
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/pl-errors': 1.4.28
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/computable': 2.9.7
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/pl-errors': 1.4.31
+ '@milaboratories/ts-helpers': 1.8.5
denque: 2.1.0
utility-types: 3.11.0
zod: 3.25.76
- '@milaboratories/ptabler-expression-js@1.2.33':
+ '@milaboratories/ptabler-expression-js@1.2.35':
dependencies:
- '@platforma-open/milaboratories.software-ptabler.schema': 1.15.17
+ '@platforma-open/milaboratories.software-ptabler.schema': 1.15.19
'@milaboratories/resolve-helper@1.1.3': {}
@@ -6438,16 +6496,16 @@ snapshots:
'@milaboratories/ts-configs@1.3.0': {}
- '@milaboratories/ts-helpers@1.8.4':
+ '@milaboratories/ts-helpers@1.8.5':
dependencies:
- '@milaboratories/helpers': 1.14.3
+ '@milaboratories/helpers': 1.14.4
canonicalize: 2.1.0
denque: 2.1.0
- '@milaboratories/uikit@2.15.13(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)':
+ '@milaboratories/uikit@2.15.16(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)':
dependencies:
- '@milaboratories/helpers': 1.14.3
- '@platforma-sdk/model': 1.79.27
+ '@milaboratories/helpers': 1.14.4
+ '@platforma-sdk/model': 1.80.2
'@types/d3-array': 3.2.2
'@types/d3-axis': 3.0.6
'@types/d3-scale': 4.0.9
@@ -6901,13 +6959,13 @@ snapshots:
'@platforma-open/milaboratories.runenv-python-3.12.10-scientific-slim': 1.1.0
'@platforma-open/milaboratories.runenv-python-3.12.10-torch-cuda': 0.2.0
- '@platforma-open/milaboratories.software-ptabler.schema@1.15.17':
+ '@platforma-open/milaboratories.software-ptabler.schema@1.15.19':
dependencies:
- '@milaboratories/pl-model-common': 1.46.4
+ '@milaboratories/pl-model-common': 1.47.1
- '@platforma-open/milaboratories.software-ptabler@2.1.3': {}
+ '@platforma-open/milaboratories.software-ptabler@2.1.6': {}
- '@platforma-open/milaboratories.software-ptexter@1.2.2': {}
+ '@platforma-open/milaboratories.software-ptexter@1.2.3': {}
'@platforma-open/milaboratories.software-small-binaries.hello-world-py@1.0.10': {}
@@ -6927,17 +6985,19 @@ snapshots:
'@platforma-open/milaboratories.software-small-binaries.mnz-client': 1.6.5
'@platforma-open/milaboratories.software-small-binaries.table-converter': 1.3.5
- '@platforma-sdk/block-tools@2.11.10(@types/node@25.9.1)':
+ '@platforma-sdk/block-tools@2.12.7(@types/node@25.9.1)':
dependencies:
+ '@aws-sdk/client-ecr-public': 3.859.0
'@aws-sdk/client-s3': 3.859.0
'@inquirer/prompts': 7.10.1(@types/node@25.9.1)
'@milaboratories/pl-http': 1.2.4
- '@milaboratories/pl-model-backend': 1.4.13
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
+ '@milaboratories/pl-model-backend': 1.4.16
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
'@milaboratories/resolve-helper': 1.1.3
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/ts-helpers': 1.8.5
'@platforma-sdk/blocks-deps-updater': 2.2.0
+ '@platforma-sdk/package-builder-lib': 1.2.0
canonicalize: 2.1.0
commander: 15.0.0
lru-cache: 11.5.1
@@ -6949,25 +7009,29 @@ snapshots:
transitivePeerDependencies:
- '@types/node'
- aws-crt
+ - bare-abort-controller
+ - bare-buffer
+ - react-native-b4a
'@platforma-sdk/blocks-deps-updater@2.2.0':
dependencies:
yaml: 2.9.0
- '@platforma-sdk/model@1.79.27':
+ '@platforma-sdk/model@1.80.2':
dependencies:
- '@milaboratories/helpers': 1.14.3
+ '@milaboratories/helpers': 1.14.4
'@milaboratories/pl-error-like': 1.12.10
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/pl-model-middle-layer': 1.30.11
- '@milaboratories/ptabler-expression-js': 1.2.33
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/pl-model-middle-layer': 1.30.13
+ '@milaboratories/ptabler-expression-js': 1.2.35
canonicalize: 2.1.0
es-toolkit: 1.47.0
fast-json-patch: 3.1.1
+ lru-cache: 11.5.1
utility-types: 3.11.0
zod: 3.25.76
- '@platforma-sdk/package-builder-lib@1.1.0':
+ '@platforma-sdk/package-builder-lib@1.2.0':
dependencies:
'@aws-sdk/client-s3': 3.859.0
'@aws-sdk/lib-storage': 3.859.0(@aws-sdk/client-s3@3.859.0)
@@ -6983,9 +7047,9 @@ snapshots:
- bare-buffer
- react-native-b4a
- '@platforma-sdk/package-builder@3.14.0':
+ '@platforma-sdk/package-builder@3.14.1':
dependencies:
- '@platforma-sdk/package-builder-lib': 1.1.0
+ '@platforma-sdk/package-builder-lib': 1.2.0
commander: 15.0.0
winston: 3.19.0
transitivePeerDependencies:
@@ -6994,22 +7058,22 @@ snapshots:
- bare-buffer
- react-native-b4a
- '@platforma-sdk/tengo-builder@4.0.15':
+ '@platforma-sdk/tengo-builder@4.0.18':
dependencies:
- '@milaboratories/pl-model-backend': 1.4.13
+ '@milaboratories/pl-model-backend': 1.4.16
'@milaboratories/resolve-helper': 1.1.3
'@milaboratories/tengo-tester': 1.6.4
- '@milaboratories/ts-helpers': 1.8.4
+ '@milaboratories/ts-helpers': 1.8.5
commander: 15.0.0
winston: 3.19.0
- '@platforma-sdk/test@1.79.28(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@7.3.5(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))':
+ '@platforma-sdk/test@1.80.5(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@7.3.5(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))':
dependencies:
- '@milaboratories/computable': 2.9.6
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/pl-middle-layer': 1.65.3(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)
- '@milaboratories/pl-tree': 1.12.18
- '@platforma-sdk/model': 1.79.27
+ '@milaboratories/computable': 2.9.7
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/pl-middle-layer': 1.66.4(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)
+ '@milaboratories/pl-tree': 1.13.1
+ '@platforma-sdk/model': 1.80.2
'@vitest/coverage-istanbul': 4.1.8(vitest@4.0.18(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))
vitest: 4.1.8(@types/node@25.9.1)(@vitest/coverage-istanbul@4.1.8)(vite@7.3.5(@types/node@25.9.1)(lightningcss@1.32.0)(yaml@2.9.0))
transitivePeerDependencies:
@@ -7033,13 +7097,13 @@ snapshots:
- supports-color
- vite
- '@platforma-sdk/test@1.79.28(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@8.0.16(@types/node@25.9.1)(esbuild@0.27.7)(yaml@2.9.0))':
+ '@platforma-sdk/test@1.80.5(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)(vite@8.0.16(@types/node@25.9.1)(esbuild@0.27.7)(yaml@2.9.0))':
dependencies:
- '@milaboratories/computable': 2.9.6
- '@milaboratories/pl-client': 3.13.2
- '@milaboratories/pl-middle-layer': 1.65.3(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)
- '@milaboratories/pl-tree': 1.12.18
- '@platforma-sdk/model': 1.79.27
+ '@milaboratories/computable': 2.9.7
+ '@milaboratories/pl-client': 3.14.2
+ '@milaboratories/pl-middle-layer': 1.66.4(@bytecodealliance/preview2-shim@0.17.9)(@types/node@25.9.1)
+ '@milaboratories/pl-tree': 1.13.1
+ '@platforma-sdk/model': 1.80.2
'@vitest/coverage-istanbul': 4.1.8(vitest@4.1.8)
vitest: 4.1.8(@types/node@25.9.1)(@vitest/coverage-istanbul@4.1.8)(vite@8.0.16(@types/node@25.9.1)(esbuild@0.27.7)(yaml@2.9.0))
transitivePeerDependencies:
@@ -7063,12 +7127,13 @@ snapshots:
- supports-color
- vite
- '@platforma-sdk/ui-vue@1.79.27(@bytecodealliance/preview2-shim@0.17.9)(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)':
+ '@platforma-sdk/ui-vue@1.80.4(@bytecodealliance/preview2-shim@0.17.9)(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)':
dependencies:
- '@milaboratories/pf-spec-driver': 1.4.18(@bytecodealliance/preview2-shim@0.17.9)
- '@milaboratories/pl-model-common': 1.46.4
- '@milaboratories/uikit': 2.15.13(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)
- '@platforma-sdk/model': 1.79.27
+ '@milaboratories/columns-collection-driver': 0.2.1
+ '@milaboratories/pf-spec-driver': 1.4.21(@bytecodealliance/preview2-shim@0.17.9)
+ '@milaboratories/pl-model-common': 1.47.1
+ '@milaboratories/uikit': 2.15.16(@vue/compiler-dom@3.5.35)(@vue/server-renderer@3.5.35(vue@3.5.24(typescript@6.0.3)))(typescript@6.0.3)
+ '@platforma-sdk/model': 1.80.2
'@types/d3-format': 3.0.4
'@types/node': 24.5.2
'@types/semver': 7.7.1
@@ -7101,12 +7166,12 @@ snapshots:
- typescript
- universal-cookie
- '@platforma-sdk/workflow-tengo@6.6.5':
+ '@platforma-sdk/workflow-tengo@6.7.2':
dependencies:
- '@milaboratories/pframes-rs-wasip2': 1.1.52
+ '@milaboratories/pframes-rs-wasip2': 1.1.55
'@milaboratories/software-pframes-conv': 2.2.9
- '@platforma-open/milaboratories.software-ptabler': 2.1.3
- '@platforma-open/milaboratories.software-ptexter': 1.2.2
+ '@platforma-open/milaboratories.software-ptabler': 2.1.6
+ '@platforma-open/milaboratories.software-ptexter': 1.2.3
'@platforma-open/milaboratories.software-small-binaries': 2.1.1
'@protobuf-ts/grpc-transport@2.11.1(@grpc/grpc-js@1.13.5)':
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 6af935c..83d87d9 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -10,13 +10,13 @@ catalog:
"@milaboratories/ts-builder": 1.6.0
"@milaboratories/ts-configs": 1.3.0
"typescript": ~5.9.3
- "@platforma-sdk/workflow-tengo": 6.6.5
- "@platforma-sdk/block-tools": 2.11.10
- "@platforma-sdk/model": 1.79.27
- "@platforma-sdk/ui-vue": 1.79.27
- "@platforma-sdk/test": 1.79.28
- "@platforma-sdk/tengo-builder": 4.0.15
- "@platforma-sdk/package-builder": 3.14.0
+ "@platforma-sdk/workflow-tengo": 6.7.2
+ "@platforma-sdk/block-tools": 2.12.7
+ "@platforma-sdk/model": 1.80.2
+ "@platforma-sdk/ui-vue": 1.80.4
+ "@platforma-sdk/test": 1.80.5
+ "@platforma-sdk/tengo-builder": 4.0.18
+ "@platforma-sdk/package-builder": 3.14.1
"@platforma-sdk/blocks-deps-updater": 2.2.0
"vue": 3.5.24
diff --git a/software/src_python/main.py b/software/src_python/main.py
index 420d358..688ccfe 100644
--- a/software/src_python/main.py
+++ b/software/src_python/main.py
@@ -64,6 +64,7 @@
import json
import multiprocessing as mp
import os
+import re
import sys
import time
from dataclasses import dataclass
@@ -87,6 +88,17 @@
# chains into small ones.
DEFAULT_TOKEN_BUDGET = 16384
+# GPU token-budget auto-sizing (see resolve_gpu_token_budget). On CUDA the token
+# budget is what bounds VRAM per forward pass, so we scale it from the VRAM the
+# workflow allocated (PLATFORMA_GPU_MEMORY) — mirroring how --max-memory-gb sizes
+# the host-RAM path. Tokens-per-GB is deliberately conservative (~2× headroom vs
+# the measured hidden-state cost of the widest wired model); the halve-on-OOM
+# retry in Embedder._forward is the backstop if a forward still overshoots.
+GPU_TOKENS_PER_GB = 4096
+GPU_RESERVE_GB = 1.0 # fragmentation + attention/temporary buffers headroom
+MIN_TOKEN_BUDGET = 4096 # floor: keep batches large enough to amortise kernel launches
+MAX_TOKEN_BUDGET = 131072 # ceiling: past this, padding waste and scheduling dominate
+
# Single process by default; the GPU tier always runs single-process regardless.
# Opt into CPU fan-out with --workers N (or 0 to auto-size from the CPU budget).
DEFAULT_WORKERS = 1
@@ -207,6 +219,57 @@ def estimate_model_gb(model_path: str) -> float:
return gb if gb > 0 else 1.0 # fall back to ~1 GB if nothing is found
+def parse_gpu_memory_env() -> float:
+ """VRAM the workflow allocated to this exec, in GB, from PLATFORMA_GPU_MEMORY.
+
+ The backend emits that env in one of two shapes: a plain byte count (local
+ exec) or a k8s/SI quantity like ``16Gi`` / ``8G`` (the Kueue job template).
+ Returns 0.0 when the env is unset or unparseable — the caller then falls back
+ to the static token-budget default."""
+ raw = os.environ.get("PLATFORMA_GPU_MEMORY", "").strip()
+ if not raw:
+ return 0.0
+ if raw.isdigit(): # local exec: raw bytes
+ return int(raw) / 1e9
+ m = re.fullmatch(r"(\d+(?:\.\d+)?)\s*([KMGTP]i?)?B?", raw) # k8s / SI quantity
+ if not m:
+ log_message(f"could not parse PLATFORMA_GPU_MEMORY={raw!r}; using default token budget",
+ "WARNING")
+ return 0.0
+ value = float(m.group(1))
+ suffix = m.group(2) or ""
+ binary = {"Ki": 2 ** 10, "Mi": 2 ** 20, "Gi": 2 ** 30, "Ti": 2 ** 40, "Pi": 2 ** 50}
+ decimal = {"K": 1e3, "M": 1e6, "G": 1e9, "T": 1e12, "P": 1e15}
+ mult = binary.get(suffix, decimal.get(suffix, 1.0))
+ return value * mult / 1e9
+
+
+def resolve_gpu_token_budget(args, device, model_path: str, model_family: str) -> int:
+ """Tokens per forward pass, sized from the allocated VRAM on the GPU path.
+
+ On CUDA the token budget is the lever that bounds VRAM, so we size it from the
+ VRAM the workflow requested (PLATFORMA_GPU_MEMORY): a larger request → larger
+ batches → higher throughput; a smaller request stays safe. This is the GPU
+ analogue of ``--max-memory-gb`` for host RAM. An explicit --token-budget wins;
+ off the CUDA path, or with no VRAM signal, we keep the static default. The
+ halve-on-OOM retry in Embedder._forward remains the backstop if a forward
+ still overshoots the estimate."""
+ if args.token_budget is not None and args.token_budget > 0:
+ return args.token_budget # explicit operator override always wins
+ if device.type != "cuda": # budget only bounds VRAM; CPU/MPS keep the default
+ return DEFAULT_TOKEN_BUDGET
+ gpu_gb = parse_gpu_memory_env()
+ if gpu_gb <= 0:
+ return DEFAULT_TOKEN_BUDGET
+ # Standard HF encoders load fp16 on CUDA; custom (trust_remote_code) models stay
+ # fp32 — mirror Embedder.dtype so the weights term matches the resident copy.
+ fp16 = model_family != "hf-custom"
+ weights_gb = estimate_model_gb(model_path) * (0.5 if fp16 else 1.0)
+ avail_gb = max(0.5, gpu_gb - weights_gb - GPU_RESERVE_GB)
+ budget = int(avail_gb * GPU_TOKENS_PER_GB)
+ return max(MIN_TOKEN_BUDGET, min(budget, MAX_TOKEN_BUDGET))
+
+
def resolve_parallelism(args, device, model_path: str) -> "tuple[int, int]":
"""Decide (workers, threads_per_worker) for the run.
@@ -1207,8 +1270,10 @@ def main() -> int:
"all non-pad tokens.")
parser.add_argument("--max-length", type=int, default=DEFAULT_MAX_LENGTH,
help="Max residue tokens incl. specials; longer sequences truncate from the C-terminus")
- parser.add_argument("--token-budget", type=int, default=DEFAULT_TOKEN_BUDGET,
- help="Max tokens (batch × padded length) per forward pass")
+ parser.add_argument("--token-budget", type=int, default=None,
+ help="Max tokens (batch × padded length) per forward pass. On CUDA, "
+ "auto-sized from allocated VRAM (PLATFORMA_GPU_MEMORY) unless set here. "
+ f"Unset elsewhere defaults to {DEFAULT_TOKEN_BUDGET}.")
parser.add_argument("--workers", type=int, default=DEFAULT_WORKERS,
help="CPU inference processes. 1 = single process (default); "
"0 = auto (size from --cpus: ~2 threads/worker, total ≈ cpus, "
@@ -1247,6 +1312,12 @@ def main() -> int:
device = resolve_device(plan.device)
+ # Tokens per forward pass. On CUDA this is sized from the allocated VRAM
+ # (PLATFORMA_GPU_MEMORY) so the workflow's VRAM request drives the GPU batch
+ # size; elsewhere it is the static default. Computed once and shared by every
+ # embedder below (they all take it as `token_budget`).
+ token_budget = resolve_gpu_token_budget(args, device, args.model_path, args.model_family)
+
# Decide CPU parallelism (workers × intra-op threads). Auto sizing and the
# GPU/MPS single-process guard live in resolve_parallelism.
workers, threads_per_worker = resolve_parallelism(args, device, args.model_path)
@@ -1254,27 +1325,27 @@ def main() -> int:
trust_remote_code = args.model_family == "hf-custom"
if args.model_family == "ablang2":
# The pip model runs single-process regardless of --workers (see class doc).
- embedder = AbLang2Embedder(args.model_path, device, args.max_length, args.token_budget,
+ embedder = AbLang2Embedder(args.model_path, device, args.max_length, token_budget,
input_kind=args.input_kind)
workers, threads_per_worker = 1, 0
parallel_note = "ablang2 (single process)"
elif trust_remote_code:
# Custom trust_remote_code model (PeptideCLM-2): single process — spawn + the
# dynamic module import is fragile. Load once in-process; let torch use all cores.
- embedder = Embedder(args.model_path, device, args.max_length, args.token_budget,
+ embedder = Embedder(args.model_path, device, args.max_length, token_budget,
threads=0, input_kind=args.input_kind, trust_remote_code=True,
emb_layer=args.emb_layer, pool_special_tokens=args.pool_special_tokens)
workers, threads_per_worker = 1, 0
parallel_note = "hf-custom (single process)"
elif workers > 1:
- embedder = ParallelEmbedder(args.model_path, device, args.max_length, args.token_budget,
+ embedder = ParallelEmbedder(args.model_path, device, args.max_length, token_budget,
workers, threads_per_worker, input_kind=args.input_kind,
trust_remote_code=trust_remote_code,
emb_layer=args.emb_layer,
pool_special_tokens=args.pool_special_tokens)
parallel_note = f"workers={workers}×{threads_per_worker} threads/worker"
else:
- embedder = Embedder(args.model_path, device, args.max_length, args.token_budget,
+ embedder = Embedder(args.model_path, device, args.max_length, token_budget,
threads=threads_per_worker, input_kind=args.input_kind,
trust_remote_code=trust_remote_code,
emb_layer=args.emb_layer, pool_special_tokens=args.pool_special_tokens)
@@ -1284,7 +1355,8 @@ def main() -> int:
# Record device + checkpoint at startup so the operator sees what ran.
log_message(f"device={device.type} dtype={embedder.dtype} model={model_name} dim={embedder.dim} "
- f"{parallel_note} (requested={plan.device}, scopes={len(plan.scopes)})",
+ f"token_budget={token_budget} {parallel_note} "
+ f"(requested={plan.device}, scopes={len(plan.scopes)})",
"STEP")
stats: dict = {
diff --git a/ui/src/pages/MainPage.vue b/ui/src/pages/MainPage.vue
index 3110c99..cb23df9 100644
--- a/ui/src/pages/MainPage.vue
+++ b/ui/src/pages/MainPage.vue
@@ -122,7 +122,10 @@ const slowOnCpu = computed(() => {
:step="1"
:maxValue="1012"
>
- Host memory for each embedding batch. Default: 32 GiB.
+
+ Host memory for each embedding batch. Leave empty to size automatically from device and
+ input; set to override.
+
{
:step="1"
:maxValue="128"
>
- CPU cores for each embedding batch. Default: 16.
+
+ CPU cores for each embedding batch. Leave empty to size automatically from device and
+ input; set to override.
+
diff --git a/workflow/src/compute-embeddings.tpl.tengo b/workflow/src/compute-embeddings.tpl.tengo
index 641f23b..2f25ac9 100644
--- a/workflow/src/compute-embeddings.tpl.tengo
+++ b/workflow/src/compute-embeddings.tpl.tengo
@@ -34,8 +34,12 @@ self.body(func(inputs) {
modelTag := inputs.modelTag // checkpoint id + --model-name identity
keyCol := inputs.keyCol // entity-key column header in the batch TSV
device := inputs.device // "cpu" | "gpu" (gates the GPU request)
- cpu := is_undefined(inputs.cpu) ? 16 : inputs.cpu
- memGiB := is_undefined(inputs.mem) ? 32 : inputs.mem
+
+ // Advanced-settings resource overrides (either may be unset). When present, the
+ // static value wins over the data-driven formula for that dimension, on both the
+ // CPU and GPU paths (below). mem is given in GiB.
+ cpuOverride := inputs.cpu // number | undefined
+ ramOverride := is_undefined(inputs.mem) ? undefined : string(inputs.mem) + "GiB"
// Per-model recipe (inputKind, loader family, pairMode, embLayer, poolSpecials)
// comes from the central registry (models.lib) — the single source of truth,
@@ -71,10 +75,8 @@ self.body(func(inputs) {
builder := exec.builder().
software(soft).
- mem(string(memGiB) + "GiB").
- cpu(cpu).
addAsset(modelAsset, "model").
- addFile("batch.tsv", batchFile).
+ addFile("batch.tsv", batchFile, { tag: "batch" }).
writeFile("plan.json", planJson).
arg("--input").arg("batch.tsv").
arg("--plan").arg("plan.json").
@@ -97,13 +99,45 @@ self.body(func(inputs) {
// @TODO: Update SDK and get mkDir("embeddings") once the fix that
// prevents it to create "[\"embeddings\"]" folder is released.
- // GPU vs CPU tier is decided by the plan's device.
+ // GPU vs CPU tier is decided by the plan's device (itself set from exec.hasGpu in
+ // main.tpl). Each path declares its resources via `.resources()`; an advanced-
+ // settings override (cpuOverride / ramOverride) wins per dimension where set.
+ f := exec.formula
if device == "gpu" {
- builder.gpuMemory("16GiB")
+ // GPU: the accelerator does the work in ONE streaming process, so the host only
+ // tokenizes and writes Parquet interleaved with the forward pass — no separable
+ // CPU-heavy phase (the heavy PColumn->batch-TSV shaping is upstream CPU execs).
+ // So keep the host footprint MINIMAL and sized to fit the cheapest fractional-L4
+ // node: cpu 2 + ram 8 GiB fit a g6f.xlarge (4 vCPU / 16 GiB), and the model-tiered
+ // vram (3 GiB small / 6 GiB large, models.gpuVramGiB) selects gpu-3g / gpu-6g —
+ // never the 4×L40S g6e.12xlarge the old 16/32/16 request forced. vram rides to the
+ // runner as PLATFORMA_GPU_MEMORY (sizes the token budget); host RAM via the
+ // --max-memory-gb {system.ram.gb} arg above. No --workers/--cpus (single process).
+ builder.resources({
+ onGPU: {
+ cpu: is_undefined(cpuOverride) ? 2 : cpuOverride,
+ ram: is_undefined(ramOverride) ? "8GiB" : ramOverride,
+ vram: string(models.gpuVramGiB(modelTag)) + "GiB"
+ }
+ })
} else {
builder.
arg("--workers").arg("0").
arg("--cpus").argExpr("{system.cpu}")
+
+ // CPU: throughput scales with cores (workers × intra-op threads), and the
+ // per-batch work ~= its token volume ~= the batch TSV byte size. Size cores
+ // from it (4..16) and RAM to 2 GiB/core (8..32 GiB) so ~cores/2 resident model
+ // copies fit — the fan-out the runner auto-sizes from --max-memory-gb. Both
+ // dimensions carry a .staticFallback equal to the old fixed 16 / 32 GiB, used
+ // on backends that cannot evaluate resource formulas.
+ cores := f.size("batch").dividedBy(f.mib(2)).between(4, 16)
+ builder.resources({
+ onCPU: {
+ cpu: is_undefined(cpuOverride) ? cores.staticFallback(16) : cpuOverride,
+ ram: is_undefined(ramOverride) ? cores.times(f.gib(2)).staticFallback("32GiB") : ramOverride
+ }
+ })
}
run := builder.
diff --git a/workflow/src/compute-stats.tpl.tengo b/workflow/src/compute-stats.tpl.tengo
index d0434f0..e1b1438 100644
--- a/workflow/src/compute-stats.tpl.tengo
+++ b/workflow/src/compute-stats.tpl.tengo
@@ -81,11 +81,26 @@ self.body(func(inputs) {
// Canonical encoding keeps the plan bytes deterministic.
planJson := string(canonical.encode({ device: inputs.device, scopes: planScopes }))
+ // The counting pass loads the whole source TSV into memory (read_csv, all columns
+ // Utf8), so its RAM tracks the source size rather than a flat budget: ~3× the TSV
+ // bytes (DataFrame + transient copies + arrow) on a 2 GiB base, floored at the old
+ // 4 GiB for small inputs and capped at 32 GiB. cpu gets a couple of cores on large
+ // files for the parse. Both fall back to the old fixed 4 GiB / 1 core on backends
+ // that cannot evaluate resource formulas. (The seqTb builder above stays light —
+ // ptabler streams with disk spill, so the metaInput 1 core / 4 GiB is enough.)
+ f := exec.formula
run := exec.builder().
software(soft).
- cpu(cpu).
- mem(string(memGiB) + "GiB").
- addFile("source.tsv", sourceTsv).
+ // Register the tagged input before the formula that references it (tag lookup
+ // is resolved at build time, so order is not functionally required — but this
+ // mirrors compute-embeddings and removes any ambiguity).
+ addFile("source.tsv", sourceTsv, { tag: "source" }).
+ resources({
+ onCPU: {
+ cpu: f.size("source").dividedBy(f.gib(1)).between(1, 4).staticFallback(1),
+ ram: f.size("source").times(3).plus(f.gib(2)).between(f.gib(4), f.gib(32)).staticFallback("4GiB")
+ }
+ }).
writeFile("plan.json", planJson).
arg("--stats-only").
arg("--input").arg("source.tsv").
diff --git a/workflow/src/main.tpl.tengo b/workflow/src/main.tpl.tengo
index b01306a..84a01a4 100644
--- a/workflow/src/main.tpl.tengo
+++ b/workflow/src/main.tpl.tengo
@@ -109,9 +109,17 @@ wf.body(func(args) {
minBatch = MIN_BATCH_GPU
}
- // Advanced resource overrides for the embedding execs.
- embedCpu := is_undefined(args.cpu) ? 16 : args.cpu
- embedMemGiB := is_undefined(args.mem) ? 32 : args.mem
+ // Advanced resource overrides for the embedding execs. Passed through RAW
+ // (possibly unset) as metaExtra below: compute-embeddings uses a static override
+ // where present and its data-driven resource formula where absent. metaExtra is
+ // scheduling-only (CID-transparent), so conditionally including a key is dedup-safe.
+ embedMeta := {}
+ if !is_undefined(args.cpu) {
+ embedMeta.cpu = smart.createJsonResource(args.cpu)
+ }
+ if !is_undefined(args.mem) {
+ embedMeta.mem = smart.createJsonResource(args.mem)
+ }
// Provenance trace seeded from the input dataset. The trace label and id carry
// the MODEL, so two columns embedding the same scope with different models get
@@ -226,10 +234,7 @@ wf.body(func(args) {
keyCol: smart.createJsonResource(keyAxisName),
device: smart.createJsonResource(device)
},
- metaExtra: {
- cpu: smart.createJsonResource(embedCpu),
- mem: smart.createJsonResource(embedMemGiB)
- }
+ metaExtra: embedMeta
}
)
diff --git a/workflow/src/models.lib.tengo b/workflow/src/models.lib.tengo
index ad170cd..bda1964 100644
--- a/workflow/src/models.lib.tengo
+++ b/workflow/src/models.lib.tengo
@@ -88,6 +88,29 @@ label := func(tag) {
return m.label
}
+// GPU VRAM to request for a tag, in GiB. This is a SCHEDULING request — it selects
+// the GPU node tier (backend maps it to the `platforma.bio/gpu-memory-gib` node
+// selector) and rides to the runner as PLATFORMA_GPU_MEMORY, which sizes the GPU
+// token budget (see software main.py resolve_gpu_token_budget). It is NOT a hard
+// cap: the forward pass is token-budgeted with a halve-on-OOM retry.
+//
+// Kept as small as safely fits so the job lands on the CHEAP fractional-L4 g6f
+// tiers, never the big 4×L40S g6e.12xlarge (gpu-96g). Two tiers by model width:
+// - dim <= 768 (BERT-base-scale: H3BERTa/VHHBERT/TCR-BERT, AbLang2, ESM-2 150M)
+// -> 3 GiB -> gpu-3g (g6f.xlarge). Footprint ~1.5 GiB (CUDA context + <=0.3 GiB
+// fp16 weights + a few 100 MB activations), so 3 GiB has margin even at the
+// default token budget.
+// - dim >= 1024 (ESM-2 650M, CurrAb, fp32 PeptideCLM-2) -> 6 GiB -> gpu-6g
+// (g6f.2xlarge). Peak ~3.7 GiB for ESM-2 650M at the default budget; 6 GiB
+// leaves headroom and the adaptive budget shrinks batches when VRAM is tighter.
+gpuVramGiB := func(tag) {
+ m := MODELS[tag]
+ if is_undefined(m) {
+ return 6 // unknown tag: the safer of the two small tiers
+ }
+ return m.dim >= 1024 ? 6 : 3
+}
+
// Final output vector length for a (scope, model): the base width D, doubled for a
// paired Fv scope embedded by a non-joint (concat) model — VH⊕VL → 2D. Single
// chains, scFv, and joint-Fv (CurrAb/AbLang2) stay at D. undefined for an unmapped
@@ -108,5 +131,6 @@ export ll.toStrict({
resolveModelTag: resolveModelTag,
get: get,
label: label,
+ gpuVramGiB: gpuVramGiB,
outputVectorLength: outputVectorLength
})