moeru-ai/airi · warning

[GPU] Memory pressure: ${level} — ${Math.round(usage.allocat

Error message

[GPU] Memory pressure: ${level} — ${Math.round(usage.allocated / 1024 / 1024)}MB / ${Math.round(usage.budget / 1024 / 1024)}MB (models: ${usage.models.join(', ')})

What it means

The global GPU resource coordinator tracks allocated bytes per loaded model against an estimated VRAM budget (from cached WebGPU capabilities; 0 when unavailable). When allocation crosses a pressure level it emits a memory-pressure event, and getGPUCoordinator() logs this warn with allocated/budget MB and the model list. It is an advisory signal to free models or stop loading, not an error — but ignoring it usually precedes real device-lost failures.

Source

Thrown at packages/stage-ui/src/libs/inference/coordinator.ts:34

import { createLoadQueue } from './load-queue'

let coordinator: GPUResourceCoordinator | null = null
let loadQueue: LoadQueue | null = null

/**
 * Get the global GPU resource coordinator.
 * Initializes lazily from cached WebGPU capabilities.
 */
export function getGPUCoordinator(): GPUResourceCoordinator {
  if (!coordinator) {
    const capabilities = getCachedWebGPUCapabilities()
    const estimatedVRAM = capabilities?.estimatedVRAM ?? 0
    coordinator = createGPUResourceCoordinator(estimatedVRAM)

    // Log memory pressure events
    coordinator.onMemoryPressure((level) => {
      const usage = coordinator!.getUsage()
      console.warn(
        `[GPU] Memory pressure: ${level} — `
        + `${Math.round(usage.allocated / 1024 / 1024)}MB / ${Math.round(usage.budget / 1024 / 1024)}MB `
        + `(models: ${usage.models.join(', ')})`,
      )
    })
  }

  return coordinator
}

/**
 * Get the global model load queue.
 * Ensures only one model loads at a time to prevent
 * bandwidth competition and GPU memory spikes.
 */
export function getLoadQueue(): LoadQueue {
  if (!loadQueue) {
    loadQueue = createLoadQueue()

View on GitHub (pinned to 677329427f)

Solutions

  1. Unload models you are not actively using via the coordinator instead of keeping all loaded.
  2. Prefer smaller quantizations/dtypes on devices with low estimatedVRAM.
  3. Serialize loads through the model load queue (getModelLoadQueue) so peak allocation stays under budget.
  4. If capabilities caching returned 0, refresh it in a supported browser so the budget is realistic.

Example fix

// before
await kokoro.load(); await whisper.load() // both resident, pressure warn

// after
const c = getGPUCoordinator()
if (c.getUsage().allocated + estimate > c.getUsage().budget) {
  await c.release('kokoro') // free before loading the next model
}
await whisper.load()
Defensive patterns

Strategy: validation

Validate before calling

const usage = getGPUCoordinator().getUsage()
if (usage.allocated + incomingModelBytes > usage.budget) {
  // release or queue instead of loading now
}

Prevention

When it happens

Trigger: Loading multiple inference models concurrently (e.g. whisper + kokoro) plus renderer work on a GPU whose estimatedVRAM is small or was cached as 0/unknown; high quantization choices inflating allocations.

Common situations: Low-VRAM integrated GPUs; browsers where capabilities estimation fails so budget defaults to 0; users enabling every model in settings at once.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/602ec1d32ca81630. Report an issue: GitHub.