Repository navigation
fix(working-memory): reserve measured working memory for tiled VAE decodes and encodes - #9946
Open
Pfannkuchensack wants to merge 138 commits into
Open
Pfannkuchensack wants to merge 138 commits into
Pfannkuchensack wants to merge 138 commits into
Conversation
Runs each installed model family through a launched scratch server and compares PSNR, time and driver-level VRAM against accepted references. Graphs come from the frontend builders via an offline graph export; the generate submission plan is shared with the workbench.
VAE estimators return a WorkingMemoryEstimate built from fitted and analytic terms; model_on_device accepts it as working_memory=. The AutoencoderKL coefficients and their measured points move to backend/working_memory/data, checked by a data test; reservations are unchanged.
A probe records each estimated model_on_device window's device-level demand inside a calibration scope; results go to a per-device-class store under databases/working_memory. Admin endpoints start, inspect, reset and export runs; the reserved queue origin is refused for ordinary enqueues.
VAE estimators price a measured slope and base per conv backend, allocator and dtype instead of scaling one bf16 constant by element size; CogView4 gets its own lines. SD/SDXL nodes and their estimate share one run-dtype rule; on ROCm Windows an SDXL fp32 1024² decode reserves 6.2 instead of 14.6 GB and the UNet stays resident.
A lower second reading at a measured size no longer tilts a fitted line, and points that include cast weight growth no longer fit one; two shipped lines move by under 1 %.
…n fact Environment ids now include windows, linux or other, so calibrations from different operating systems are kept apart; the OS build string moves to soft fact os_build.
… runs start --calibrate submits each case through the calibration endpoint and saves the store export per server lifetime; scripts/working_memory/build_shipped.py turns exports into probe points and refits. Probe points bound estimates from below only, and the builder refuses data that the shared bound rule rejects.
# Conflicts: # docs/src/content/docs/development/Architecture/model-manager.mdx
…anager Adds a working-memory section to the model detail: plan, calibrate, stop and reset per GPU, with the measured, built-in and calibrated estimate per size. User fits from finished calibration attempts price VAE decodes within their measured range (+10 % + 256 MiB on the fitted part) and never below built-in values above it. New plan and summary routes; summary reports lines shared with other models and returns 404 for unknown models.
…calibration Judges allocator fragmentation per calibration attempt with one rule shared with the shipped-data builder, and moves other models off the GPU before a measured calibration lock. User fits use the shipped 5 % margin; the plan sizes cases from the capacity the cache will grant, including memory the driver keeps after earlier runs. The table marks uncounted sizes with their reason and explains each value column.
# Conflicts: # invokeai/backend/util/vae_working_memory.py # tests/app/invocations/test_flux2_working_memory.py
# Conflicts: # invokeai/backend/util/vae_working_memory.py
Main added useNsfwChecker and useWatermark to the generation project settings; exported calibration and E2E graphs run without both, as the defaults do.
…ser-calibration # Conflicts: # invokeai/frontend/webv2/performance/browser-baseline.json # invokeai/frontend/webv2/scripts/mock-backend-fixtures.test.mjs # invokeai/frontend/webv2/scripts/mock-backend.mjs
…e baseline Raises otherRawBytes to the measured 215114 B on every route; the 3791 B growth are the Model Manager working-memory strings.
…f the model page The section starts collapsed and shows the GPU with the calibration state, or the run progress, in its header; the plan loads on first open. The mock prices sizes above the measured range with the larger of the user line and built-in, as the server does.
Main added useNsfwChecker and useWatermark to the generation project settings; exported calibration and E2E graphs run without both, as the defaults do.
…sured lines Prices the Z-Image denoise through an EstimatorSpec whose per-token lines are fitted from fresh-process measurements on CUDA and ROCm, with an fp8 cast term and the legacy constants as the floor where nothing was measured. Fitted lines can now run over tokens; the builder takes measured point files, and calibration scripts share the server runtime and the probe's measurement window.
…-user-calibration # Conflicts: # invokeai/frontend/webv2/scripts/mock-backend.mjs
…ue completion as canceled The runner tells the final observation whether the queue committed the item's completion, so a cleared row overrides a completion recorded ahead of the queue while a pruned completed one keeps it.
…ser-calibration # Conflicts: # docs/src/content/docs/development/Architecture/model-manager.mdx
…-user-calibration # Conflicts: # invokeai/frontend/webv2/performance/browser-baseline.json # invokeai/frontend/webv2/src/app/router.tsx # invokeai/frontend/webv2/src/features/models/ui/ModelsUiContext.tsx # invokeai/frontend/webv2/src/features/models/ui/detail/ModelDetail.tsx
Add an NVML backend with the WDDM sampler's interface; on Linux the runner uses it and pins the server to the selected GPU. Linux adapters are keyed by UUID for locks and selection, so identical cards can run side by side; records never store the UUID. Bundles also redact POSIX paths in free text.
The cache logs a tokenizer at 0.0% of 0.03MB, which made every FLUX record invalid. Residency records the logged total size, and loads under 1 MB count as resident in the checks and the report.
Measured on an RTX PRO 6000 Blackwell: NVML's per-process delta equals reserved growth, the first window adds first-use memory. The hardware test asserts the verified nvml method on Linux CUDA; docs note that containers without the host PID namespace fall back to torch-only.
…y-e2e-calibration # Conflicts: # docs/src/content/docs/development/Guides/family-e2e.mdx # scripts/family_e2e/__main__.py # scripts/family_e2e/records.py # scripts/family_e2e/report.py # scripts/family_e2e/runner.py # tests/family_e2e/fake_invokeai_server.py # tests/family_e2e/test_report.py
…runs' into feat/family-e2e-calibration
The calibration status test keeps an unverified case with Linux ROCm's fdinfo reader.
joshistoast
requested changes
Oct 23, 2026
joshistoast
left a comment
Collaborator
There was a problem hiding this comment.
One actionable calibration-planning defect affecting FLUX-family models configured for float32.
|
|
||
|
|
||
| _SD = DecodeLines("vae.sd", ("fp16", "fp32"), precision_setting=True) | ||
| _FLUX = DecodeLines("vae.flux", ("bf16",)) |
Collaborator
There was a problem hiding this comment.
[P2] Derive calibration precision from the configured VAE dtype
FLUX.1, FLUX.2, and Z-Image calibration plans always use bf16 estimates, even when the loader preserves configured float32 precision. On a 16 GiB device, this selects a 1408×1408 case requiring approximately 20.95 GiB; planning with fp32 instead selects 1088×1088. With partial loading enabled, the oversized case runs partially resident and its measurements are excluded from fitting. Planning should use the loader’s configured-precision rules.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tiled VAE operations reserved the untiled line at the tile area × 1.25, and
vae.fluxadded analytic full-image terms on top. Fresh-process measurements on an RTX 4090 and an RX 9060 XT show the formula is wrong in both directions:The tiled estimates now come from measured lines:
tile_size <= 0to the VAE's own tile, as the nodes do.Default allocators, measured demand in GiB, and the reservation as a multiple of it (main → this PR):
Related Issues / Discussions
QA Instructions
Measured points
working_memory/data/vae.json. They come from the newscripts/calibrate_vae_tiling_working_memory.py, which runs each operation the way its node runs it, inside themodel_on_devicewindow.cudaMallocAsync; RX 9060 XT (torch 2.13+rocm10.0, Windows), expandable segments and native.vae.flux,vae.flux2andvae.sd(fp16/fp32), decode and encode.Bounds
UPPER_BOUND_EXCEPTIONSwith their cause and exact ratio: 16 on the default allocators, 90 undercudaMallocAsyncand MIOpen native.Tests
uv run --no-sync pytest -n 4over the working-memory, calibration-service, invocation, builder and calibration-script suites: 4785 passed.Review
Resolved findings
Remaining limits
cudaMallocAsyncand MIOpen native it over-reserves by up to about 2.35× and 1.72× at some tile and size combinations. That is extra offloading, never a failure.cudaMallocAsync, one MIOpen-native encode, and FLUX.2 decode at a 1024 px tile on cuDNN native.Compatibility / Rollout
vae.sd,vae.fluxandvae.flux2move to estimator version 3. Stored user calibrations of those estimators from an earlier version are shown as unusable and need a new calibration. Neither version has been released yet.vae.jsongrows to about 1.3 MB (32 KB gzipped).Checklist
What's Newcopy (if doing a release after this PR)Need help on this PR? Tag
@codesmith-botwith what you need.