stanfordnlp/CoreNLP · error · RuntimeException

Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunct

Error message

Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()

What it means

During CRFNonLinearLogConditionalObjectiveFunction.calculate(), the accumulated log-probability of the document under the non-linear CRF model became NaN. The library treats NaN probabilities as an unrecoverable numerical failure (usually from exploding/vanishing activations, zero denominator in softmax, or inconsistent weights), so calculate() throws a RuntimeException instead of returning a NaN value to the optimizer.

Solutions

  1. Check the weight vector x for NaN/Inf before calling calculate(); if present, restart training with lower learning rate and smaller maxQNIter/QuasiNewton parameters.
  2. Normalize/scale input feature values so activations stay in a numerically safe range.
  3. Try flags.softmaxOutputLayer with proper flags.sparseOutputLayer or flags.tieOutputLayer, or disable useOutputLayer to use the stable linear model.
  4. Reduce regularization or inspect training data for pathological (huge or constant) features causing overflow.

Example fix

// before
if (Double.isNaN(prob)) { // shouldn't be the case
  throw new RuntimeException("Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()");
}
// after (caller-side guard before optimization)
for (double w : x) {
  if (Double.isNaN(w) || Double.isInfinite(w)) {
    throw new IllegalArgumentException("non-finite parameter before calculate(): " + w);
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Java, before training
for (double w : initialWeights) {
  if (Double.isNaN(w) || Double.isInfinite(w))
    throw new IllegalArgumentException("initial weights must be finite");
}
// also check input features are bounded
assert featureValues.stream().allMatch(v -> Double.isFinite(v) && Math.abs(v) < 1e6);

Try / catch

// wrap training
try {
  classifier.train(trainingProps);
} catch (RuntimeException e) {
  if (e.getMessage().contains("Got NaN for prob")) {
    // restart with smaller learning rate / fewer iterations / rescaled features
  } else throw e;
}

Prevention

When it happens

Trigger: Calling calculate() (typically via a minimizer like QNMinimizer on CRFClassifier.train with useNonLinearCRF=true) when model weights passed in x contain NaN/Inf, when softmax denominators underflow to 0, or when intermediate expected counts overflow to infinity and Inf-Inf yields NaN.

Common situations: Training diverges after a too-large learning rate or bad initial weights; extremely large feature values scaled without normalization; useOutputLayer with degenerate softmax inputs; running many iterations on numeric-unstable data so weights drift to Inf/NaN.

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


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/181c42db099714be. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/ie/crf/CRFNonLinearLogConditionalObjectiveFunction.java:670

                  fVal = 1.0;
                  if (featureVal3DArr != null)
                    fVal = featureVal3DArr[i][j][n];
                  eWK[cliqueFeatures[n]] += deltaK * p * fVal;
                }
              }
            } else { // for edge features
              for (int cliqueFeature : cliqueFeatures) {
                E[cliqueFeature][k] += p;
              }
            }
          }
          if (DEBUG) log.info(" done!");
        }
      }
    }

    if (Double.isNaN(prob)) { // shouldn't be the case
      throw new RuntimeException("Got NaN for prob in CRFNonLinearLogConditionalObjectiveFunction.calculate()");
    }

    value = -prob;
    if(VERBOSE){
      log.info("value is " + value);
    }

    if (DEBUG) log.info("calculating derivative ");
    // compute the partial derivative for each feature by comparing expected counts to empirical counts
    int index = 0;
    for (int i = 0; i < E.length; i++) {
      for (int j = 0; j < E[i].length; j++) {
        derivative[index++] = (E[i][j] - Ehat[i][j]);
        if (VERBOSE) {
          log.info("linearWeights deriv(" + i + "," + j + ") = " + E[i][j] + " - " + Ehat[i][j] + " = " + derivative[index - 1]);
        }
      }
    }

View on GitHub (pinned to 1b7edd19c4)