MILAB-6480: optimize embedding resource requests with fluent formulas API - #5
Conversation
… API
Migrate the embedding execs to the fluent exec.formula / .resources() API
(workflow-tengo 6.7.x) and size GPU jobs to the smallest node that safely fits.
Workflow:
- compute-embeddings uses .resources({ onCPU | onGPU }) instead of a flat
16 CPU / 32 GiB / 16 GiB-VRAM request.
- GPU path: host 2 CPU / 8 GiB (single streaming process; heavy PColumn->TSV
shaping is already upstream CPU execs), VRAM model-tiered 3 GiB (dim<=768) /
6 GiB (dim>=1024). Targets the cheap fractional-L4 tiers gpu-3g (g6f.xlarge) /
gpu-6g (g6f.2xlarge) instead of forcing the 4xL40S g6e.12xlarge.
- CPU path: cores from size("batch") clamped [4,16], RAM 2 GiB/core [8,32],
.staticFallback = old fixed 16 / 32 GiB.
- compute-stats sizes RAM from source-TSV size (it full-loads the TSV via
read_csv), replacing the flat 4 GiB that could OOM on large inputs.
Software:
- On CUDA the per-forward token budget is auto-sized from allocated VRAM
(PLATFORMA_GPU_MEMORY), mirroring how --max-memory-gb sizes the host-RAM path.
Explicit --token-budget still wins; halve-on-OOM retry remains the backstop.
Model/UI:
- mem/cpu Advanced-Settings fields are now opt-in (init no longer hardcodes
32/16), so the workflow's automatic sizing applies unless the user overrides.
Pin workflow-tengo 6.6.5 -> 6.7.2.
There was a problem hiding this comment.
Code Review
This pull request optimizes compute-resource requests for sequence embeddings by transitioning from static defaults to dynamic, data-driven resource allocation. CPU and RAM requirements are now automatically sized based on input volume, and GPU VRAM is tiered by model size, allowing jobs to run on cheaper fractional-L4 instances. Additionally, on CUDA, the token budget is auto-sized from the allocated VRAM. Feedback on the changes highlights a flaw in the GPU token budget resolution logic where explicitly setting the budget to the default value would incorrectly trigger auto-sizing; updating the default argument to None is recommended to properly handle user overrides.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Addresses PR review: resolve_gpu_token_budget treated --token-budget equal to DEFAULT_TOKEN_BUDGET as 'unset' and auto-sized anyway. Default the arg to None so any explicit value wins; fall back to DEFAULT_TOKEN_BUDGET off-CUDA or with no VRAM signal. No effect on the block (the workflow never passes --token-budget) — fixes standalone CLI semantics only.
…compute-stats)
Addresses PR review (greptile): move .addFile('source.tsv', {tag:'source'}) ahead
of .resources({...f.size('source')...}) so it mirrors compute-embeddings. Purely
cosmetic — tag resolution happens at build time, so chain order was never functional
— but removes the ambiguity.
What & why
Migrates the embedding execs to the fluent
exec.formula/.resources()API (workflow-tengo 6.7.x) and sizes GPU jobs to the smallest node that safely fits, so embedding no longer over-provisions onto the scarce, expensiveg6e.12xlarge(the node type that sat Pending under capacity pressure).Changes
Workflow
compute-embeddingsnow declares.resources({ onCPU | onGPU })instead of a flat 16 CPU / 32 GiB / 16 GiB-VRAM request:gpu-3g(g6f.xlarge), 6 GiB (dim ≥ 1024) →gpu-6g(g6f.2xlarge). Never forcesg6e.12xlarge.size("batch")clamped [4,16], RAM 2 GiB/core [8,32],.staticFallback= the old fixed 16 / 32 GiB (for backends that can't evaluate formulas).compute-statssizes RAM from the source-TSV size (it full-loads the TSV viaread_csv), replacing the flat 4 GiB that could OOM on large inputs.Software (
main.py)PLATFORMA_GPU_MEMORY), mirroring how--max-memory-gbsizes the host-RAM path: a larger VRAM request → larger batches (higher throughput), a smaller one stays safe.--token-budgetstill overrides; the halve-on-OOM retry remains the backstop.Model / UI
mem/cpuAdvanced-Settings fields are now opt-in (init no longer hardcodes 32/16), so the workflow's automatic sizing applies unless the user sets a value (which then overrides per dimension). Existing projects keep any value they already had.Pins
@platforma-sdk/workflow-tengo6.6.5 → 6.7.2.Verification
Built + checked clean; validated live on a GPU backend (ESM-2 150M / CDR3):
g6e.12xlarge(4×L40S, ~$10.59/hr)g6f.xlarge(fractional L4, ~$0.24/hr)The batch pods provisioned
g6f.xlarge(gpu-3g) nodes, scheduled, ran to completion, and the stats pass succeeded.Greptile Summary
This PR replaces the flat
16 CPU / 32 GiB / 16 GiB-VRAMembedding resource request with the fluentexec.formula/.resources()API (workflow-tengo 6.7.x), right-sizing GPU jobs to cheap fractional-L4 nodes and scaling CPU jobs from actual batch volume. It also wires the Python runtime to auto-size the per-forward token budget from the allocated VRAM (PLATFORMA_GPU_MEMORY), and makesmem/cpuin the UI opt-in overrides instead of hard defaults.compute-embeddingsdeclaresonGPU: { cpu: 2, ram: 8GiB, vram: 3|6GiB }andonCPU: { cpu: f.size(\"batch\")/2MiB clamped [4,16], ram: cpu\u00d72GiB clamped [8,32] }with.staticFallback;compute-statssizes its exec RAM fromf.size(\"source\")\u00d73+2GiBreplacing the flat 4 GiB.resolve_gpu_token_budget()readsPLATFORMA_GPU_MEMORY, subtracts estimated weight footprint and a 1 GB reserve, then scales byGPU_TOKENS_PER_GB=4096; explicit--token-budgetstill wins and halve-on-OOM is the backstop.dataModel.tsno longer seedsmem: 32, cpu: 16; existing projects retain any saved value, new projects get automatic sizing.Key terms introduced or changed:
exec.formula/f\u2014 Fluent formula API for runtime-computed resource requests. New; replaces flat static values.onGPU/onCPU\u2014 Keys in.resources({})for per-path resource bundles. New.gpuVramGiB\u2014 New function returning VRAM tier: 3 GiB (dim \u2264 768) or 6 GiB (dim \u2265 1024).PLATFORMA_GPU_MEMORY\u2014 Env var now consumed bymain.pyto auto-size token budget.GPU_TOKENS_PER_GB\u2014 New constant (4096) inmain.py.resolve_gpu_token_budget\u2014 New function computing per-forward token budget from allocated VRAM.parse_gpu_memory_env\u2014 New parser forPLATFORMA_GPU_MEMORY(bytes or SI quantities).staticFallback\u2014 Formula method providing a static fallback for older backends.BlockDataV*.mem/.cpu\u2014 Changed: "Undefined \u2192 32 GiB / 16 cores" \u2192 "Undefined \u2192 auto-sized".dataModel.tsinitial state \u2014 Changed:{ embedding: {}, mem: 32, cpu: 16 }\u2192{ embedding: {} }.Confidence Score: 4/5
The resource-sizing changes are well-reasoned with safe static fallbacks on every dimension and a halve-on-OOM retry backstop; GPU VRAM tiers are conservatively chosen and validated live.
The core sizing logic is safe and tested end-to-end. The token-budget sentinel comparison against DEFAULT_TOKEN_BUDGET is a latent API fragility, and the resources()/addFile() ordering inconsistency in compute-stats is worth a second look before the next SDK bump, but neither is a current runtime failure.
software/src_python/main.py (token-budget sentinel logic) and workflow/src/compute-stats.tpl.tengo (builder chain ordering) deserve a second look.
Important Files Changed
.resources()is declared before the tagged.addFile()in the builder chain.parse_gpu_memory_env,resolve_gpu_token_budget, and related constants to auto-size the per-forward token budget from PLATFORMA_GPU_MEMORY on CUDA. Uses!= DEFAULT_TOKEN_BUDGETas the explicit-override sentinel, which is fragile.gpuVramGiBreturning the VRAM scheduling tier (3 GiB for dim ≤ 768, 6 GiB for dim ≥ 1024) with safe fallback to 6 for unknown tags.mem: 32, cpu: 16from initial block state, making resource overrides opt-in. Existing projects retain saved values; new projects get automatic sizing.metaInputs: { cpu: 1, mem: 4 }(correct — these go to the seqTb TSV builder, not the Python exec); embedMeta passes cpu/mem overrides as metaExtra to compute-embeddings.mem/cpufields across BlockDataV1/V2/V3 and BlockArgs to reflect auto-sizing instead of fixed defaults.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[wf.body in main.tpl.tengo] --> B{exec.hasGpu?} B -- gpu --> C[compute-embeddings: onGPU] B -- cpu --> D[compute-embeddings: onCPU] C --> C1["cpu: cpuOverride ?? 2 / ram: ramOverride ?? 8GiB / vram: gpuVramGiB"] C1 --> C2["gpu-3g g6f.xlarge or gpu-6g g6f.2xlarge"] D --> D1["cores = f.size(batch)/2MiB clamped 4-16 / ram = cores x 2GiB"] D1 --> D2["staticFallback: 16 cores / 32GiB"] A --> E[compute-stats: onCPU] E --> E1["cpu = f.size(source)/1GiB clamped 1-4 / ram = size x3 + 2GiB clamped 4-32GiB"] C1 --> F[PLATFORMA_GPU_MEMORY env] F --> G[parse_gpu_memory_env] G --> H["resolve_gpu_token_budget: avail = VRAM - weights - 1GB / budget = avail x 4096"] H --> I[clamp 4096 to 131072 tokens] I --> J[Embedder forward pass with halve-on-OOM backstop]%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A[wf.body in main.tpl.tengo] --> B{exec.hasGpu?} B -- gpu --> C[compute-embeddings: onGPU] B -- cpu --> D[compute-embeddings: onCPU] C --> C1["cpu: cpuOverride ?? 2 / ram: ramOverride ?? 8GiB / vram: gpuVramGiB"] C1 --> C2["gpu-3g g6f.xlarge or gpu-6g g6f.2xlarge"] D --> D1["cores = f.size(batch)/2MiB clamped 4-16 / ram = cores x 2GiB"] D1 --> D2["staticFallback: 16 cores / 32GiB"] A --> E[compute-stats: onCPU] E --> E1["cpu = f.size(source)/1GiB clamped 1-4 / ram = size x3 + 2GiB clamped 4-32GiB"] C1 --> F[PLATFORMA_GPU_MEMORY env] F --> G[parse_gpu_memory_env] G --> H["resolve_gpu_token_budget: avail = VRAM - weights - 1GB / budget = avail x 4096"] H --> I[clamp 4096 to 131072 tokens] I --> J[Embedder forward pass with halve-on-OOM backstop]Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "MILAB-6480: honor explicit --token-budge..." | Re-trigger Greptile
Context used: