stanfordnlp/CoreNLP · warning
QNInfo:update() : PROBLEM WITH DIAGONAL UPDATE
Error message
QNInfo:update() : PROBLEM WITH DIAGONAL UPDATE
What it means
QNMinimizer.QNInfo.update maintains a diagonal inverse-Hessian approximation built from s/y vector pairs. If the computed diagonal contains non-positive entries, infinities, or an extreme condition ratio (>1e12), the update is deemed corrupt and the diagonal is reset to the scalar approximation yy/sy with a warning.
Solutions
- Scale/normalize input features so the objective is well-conditioned.
- Check line-search/step-size settings and verify the gradient contains no NaNs/infinities before the update.
- Verify the function/diffFunction implementation returns correct values and gradients (a buggy gradient yields corrupt s/y pairs).
- The minimizer self-recovers by filling with yy/sy — confirm training proceeds and converges; the warning alone is not fatal.
Example fix
// before: unscaled features spanning [0, 1e9] double[] x = qn.minimize(f, 1e-4, initial, maxIters); // after — scale features to comparable ranges first for (int i = 0; i < initial.length; i++) initial[i] /= featureScale[i]; double[] x = qn.minimize(f, 1e-4, initial, maxIters);
Defensive patterns
Strategy: validation
Validate before calling
for (double v : grad) {
if (Double.isNaN(v) || Double.isInfinite(v)) {
throw new IllegalStateException("bad gradient value: " + v);
}
} Try / catch
// the minimizer already recovers by resetting d to yy/sy;
// wrap the training run and retrain with scaled features if the warning recurs
if (logWarningsContain("PROBLEM WITH DIAGONAL UPDATE")) {
retrainWithNormalizedFeatures();
} Prevention
- Normalize features to comparable scales.
- Verify diffFunction returns finite values.
- Tune step size / line search parameters.
When it happens
Trigger: update() called after a line search producing degenerate s/y pairs — e.g. y = g_new - g_old ≈ 0, non-positive curvature, or exploding values from an ill-conditioned objective or bad step size.
Common situations: Training with nearly zero gradient change between iterations; features on wildly different scales; too-large steps causing oscillation and bad curvature estimates.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Gradient is numerically zero, stopped on machine epsilon.
- LogPrior.valueAt is undefined for prior of type
- vectorName + " element " + i + " is " + vector[i]
- Cosine is not between -1 and 1: " + cosValue
- Math.exp(-lambda) +" "+ Math.pow(lambda, x) + ' ' +…
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/90877f97eca64928.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/optimization/QNMinimizer.java:776
final double newSi = newS[i];
sDs += newSi * (d[i] *= gamma) * newSi;
}
// This diagonal update was introduced by Andrew Bradley
for(int i = 0; i < d.length; i++) {
final double di = d[i], newSi = newS[i], newYi = newY[i];
d[i] = (1 - di * newSi * newSi / sDs) * di + newYi * newYi / sy;
}
// Here we make sure that the diagonal is alright
double minD = d[0], maxD = minD;
for(int i = 1; i < d.length; i++) {
final double v = d[i];
minD = v < minD ? v : minD;
maxD = v > maxD ? v : maxD;
}
// If things have gone bad, just fill with the SCALAR approx.
if(minD <= 0 || Double.isInfinite(maxD) || maxD / minD > 1e12) {
log.warn("QNInfo:update() : PROBLEM WITH DIAGONAL UPDATE");
Arrays.fill(d, yy / sy);
}
// If s is already of size mem, remove the oldest vector and free it up.
if(used == mem)
removeFirst();
// Actually add the pair.
s[used] = newS;
y[used] = newY;
rho[used] = 1 / sy;
++used;
return used;
} // end update
} // end class DiagonalQNInfo
public void setHistory(List<double[]> s, List<double[]> y) {View on GitHub (pinned to 1b7edd19c4)