PaddlePaddle/PaddleOCR · error

Detection batch output N=${String(nOut)} does not match inpu

Error message

Detection batch output N=${String(nOut)} does not match input batch ${String(preps.length)}

What it means

Thrown by det postprocess() when the batch dimension N of the output tensor does not equal the number of preprocessed inputs. The code derives nOut from the output's first axis (with a batch=1 special case) and requires it to match preps.length. A mismatch means the model was exported with a fixed batch size that disagrees with the runtime batch, or dynamic batching was lost.

Source

Thrown at paddleocr-js/packages/core/src/models/det.ts:434

  return new ort.Tensor("float32", out, [1, 1, cropOh, cropOw]);
}

function postprocess(
  context: DetRunContext,
  fullOutput: Tensor,
  preps: DetPreprocessResult[],
  params: InternalDetParams
): InternalDetBatchItem[] {
  const { cv, ort, config } = context;
  const od = fullOutput.dims;
  if (od.length !== 3 && od.length !== 4) {
    throw new Error(`Unexpected det output dims: [${od.join(", ")}]`);
  }
  const ohFull = od.length === 4 ? od[2] : od[1];
  const owFull = od.length === 4 ? od[3] : od[2];
  const nOut = od.length === 4 ? od[0] : preps.length === 1 ? 1 : od[0];
  if (nOut !== preps.length) {
    throw new Error(
      `Detection batch output N=${String(nOut)} does not match input batch ${String(preps.length)}`
    );
  }

  const maxH = Math.max(...preps.map((p) => p.dstH));
  const maxW = Math.max(...preps.map((p) => p.dstW));

  const items: InternalDetBatchItem[] = [];
  for (let i = 0; i < preps.length; i += 1) {
    const prep = preps[i];
    const { cropOh, cropOw } = detFeatureCropDims(prep.dstH, prep.dstW, maxH, maxW, ohFull, owFull);
    const planeTensor = sliceBatchedDetOutputPlane(
      ort,
      fullOutput,
      i,
      cropOh,
      cropOw,
      ohFull,

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Set batchSize (override or default) to the fixed batch size your det model was exported with — usually 1
  2. Re-export the det model with a dynamic first dimension if you need true batching
  3. Check the error message values: N=1 with input batch >1 almost always means fixed-batch-1 model
  4. Use the model assets bundled with the package, which match the runtime batching logic

Example fix

// before
const results = await detModel.predict(cv, mats, { batchSize: 8 }); // model is fixed batch=1

// after
const results = await detModel.predict(cv, mats, { batchSize: 1 }); // matches fixed-batch export
Defensive patterns

Strategy: validation

Validate before calling

// If your det model is fixed batch=1, always pass batchSize 1
const detBatchSize = 1; // match the model export
await detModel.predict(cv, mats, { batchSize: detBatchSize });

Type guard

function matchesFixedBatch(nOut: number, preps: number): boolean {
  return nOut === preps;
}

Try / catch

try { await detModel.predict(cv, mats, { batchSize: 8 }); } catch (e) {
  if (e instanceof Error && /does not match input batch/.test(e.message)) {
    await detModel.predict(cv, mats, { batchSize: 1 }); // fixed-batch model
  } else throw e;
}

Prevention

When it happens

Trigger: Running predict() with batchSize > 1 against a det model exported with fixed input batch = 1 (output N=1 while preps.length=4); or a fixed-batch model (N=4) invoked with fewer images because the last chunk is smaller than batchSize.

Common situations: User raises overrides.batchSize / defaultBatchSize for throughput without confirming the ONNX det model has dynamic batch; trailing partial chunk after chunkArray(mats, batchSize) hitting a fixed-N model; model exported with dynamic batch but the code path passing a mismatched tensor.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/02d1dfeb469f247e. Report an issue: GitHub.