stanfordnlp/CoreNLP · error · RuntimeException
Got NaN for prob in…
Error message
Got NaN for prob in CRFLogConditionalObjectiveFunctionForLOP.calculate()
What it means
CRFLogConditionalObjectiveFunctionForLOP computes a Log-Linear-Output-Pile (LOP) CRF objective; after accumulating prob across documents it throws a RuntimeException if the result is NaN. This indicates the LOP-style computation produced a non-finite log-probability, so the optimizer is stopped rather than continuing on corrupt values.
Solutions
- Re-normalize the LOP mixture/feature weights so the per-document computations stay finite.
- Split long training documents into shorter sequences to avoid log underflow.
- Validate the parameter vector for NaN/Inf before each optimizer step.
- Print intermediate per-document probs (enable VERBOSE) to locate the failing document.
- Lower the learning rate and retrain from a known-good initialization.
Example fix
// before lopCRF.calculate(x, batch, E); // throws on NaN // after boolean bad = false; for (double w : x) if (Double.isNaN(w) || Double.isInfinite(w)) bad = true; if (!bad) lopCRF.calculate(x, batch, E); else x = lastGoodCheckpoint;
Defensive patterns
Strategy: try-catch
Validate before calling
if (!isFinite(x)) x = lastGoodCheckpoint; // ensure params finite before LOP calculate
boolean isFinite(double[] v) { for (double d : v) if (!Double.isFinite(d)) return false; return true; } Type guard
static boolean isFinite(double[] v) { for (double d : v) if (Double.isNaN(d) || Double.isInfinite(d)) return false; return true; } Try / catch
try {
lopCrf.calculate(x, batch, E);
} catch (RuntimeException e) {
if (e.getMessage().contains("NaN for prob")) {
normalizeMixtureWeights();
x = lastGoodCheckpoint;
} else throw e;
} Prevention
- Keep LOP mixture weights normalized so ensemble log-probs stay finite.
- Split long documents before LOP training.
- Validate parameters each iteration for NaN/Inf.
- Start from a well-scaled initialization.
When it happens
Trigger: Calling calculate() on the LOP objective when the accumulated prob is NaN — typically from underflow in mixture/ensemble weight computations, extreme parameters, or long input sequences in the LOP training data.
Common situations: LOP-CRF training (useNA / feature mixture setups) with badly scaled mixture weights or very long documents; also seen when a prior optimization step yields non-finite weights.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Got NaN for prob in…
- Got NaN for prob in…
- Got NaN for prob in…
- Got NaN for prob in…
- gradient check failed
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/40c949b3cf678f62.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ie/crf/CRFLogConditionalObjectiveFunctionForLOP.java:414
eScales[lopIter] += (p * expected);
double[][] eOfIter = E[lopIter];
if (backpropTraining) {
for (int k = 0; k < docData[i][j].length; k++) { // k iterates over features
int featureIdx = docData[i][j][k];
if (indicesSet.contains(featureIdx)) {
eOfIter[featureIdx][l] += p;
}
}
}
}
}
}
}
}
if (Double.isNaN(prob)) { // shouldn't be the case
throw new RuntimeException("Got NaN for prob in CRFLogConditionalObjectiveFunctionForLOP.calculate()");
}
value = -prob;
if(VERBOSE){
log.info("value is " + value);
}
// compute the partial derivative for each feature by comparing expected counts to empirical counts
for (int lopIter = 0; lopIter < numLopExpert; lopIter++) {
double scale = scales[lopIter];
double observed = sumOfObservedLogPotential[lopIter];
for (int j = 0; j < numLopExpert; j++) {
observed -= scales[j] * sumOfObservedLogPotential[j];
}
observed *= scale;
double expected = eScales[lopIter];
derivative[lopIter] = (expected - observed);
if (VERBOSE) {View on GitHub (pinned to 1b7edd19c4)