Skip to content

feat: add margin, max_prob_raw, entropy, and top3_mass confidence methods - #4

Open
Jakob Drachmann Havtorn (JakobHavtorn) wants to merge 4 commits into
feat/fork-upstream-sync-allfrom
feat/confidence-methods-stacked
Open

feat: add margin, max_prob_raw, entropy, and top3_mass confidence methods#4
Jakob Drachmann Havtorn (JakobHavtorn) wants to merge 4 commits into
feat/fork-upstream-sync-allfrom
feat/confidence-methods-stacked

Conversation

@JakobHavtorn

Copy link
Copy Markdown

Summary

Adds 4 new confidence measures to NeMo's confidence_measure_bank in asr_confidence_utils.py, stacked on top of #3.

New confidence methods

Method Formula Description
margin p_max - p_second Top-2 gap — directly discriminative, no V-normalization
max_prob_raw exp(x_max) Raw softmax p_max — skips V-normalization, range [1/V, 1]
entropy 1 - H(p) / log(V) Normalized Shannon entropy using log_softmax, mapped to [0,1]
top3_mass Σ_{i≤3} p_i Sum of top-3 softmax probabilities

Changes

All changes are in nemo/collections/asr/parts/utils/asr_confidence_utils.py:

  • Added 4 entries to confidence_measure_bank
  • Updated _init_confidence_method to accept the new method names
  • Fixed margin lambda to handle 2D tensors (TDT computer passes 2D, not 3D)
  • Applied black formatting

Notes

  • margin and entropy and top3_mass cannot be post-hoc temperature-retuned (they depend on the full token distribution)
  • Only max_prob and max_prob_raw support post-hoc alpha recomputation
  • NeMo's built-in entropy variants (entropy_gibbs_lin, etc.) produce inf and values >1 — our entropy is reimplemented from scratch with log_softmax

Stacked on

- margin: p_max - p_second (top-2 probability gap)
- max_prob_raw: raw softmax probability without V-normalization
Both improve class separation when V is large (e.g. 8193 for TDT v3)
- entropy: normalized Shannon entropy using log_softmax, mapped to [0,1]
- top3_mass: sum of top-3 softmax probabilities
- Fix margin lambda to use [..., 0] instead of [:, :, 0] for 2D tensor compat
- Override entropy dispatch to use our custom implementation instead of
  NeMo's broken built-in variants (entropy_gibbs_lin etc. produce inf/values >1)
@github-actions github-actions Bot added the ASR label Aug 31, 2026
Signed-off-by: Jakob D. Havtorn <jdh@corti.ai>
Copilot AI lite review requested due to automatic review settings September 7, 2026 12:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

As implemented, new measures conflict with existing test invariants (uniform distribution expected to map to 0 for all measures) and the entropy config semantics appear to be a backward-incompatible API change that needs clarification/adjustment.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds additional confidence metrics to NeMo ASR’s per-frame confidence machinery by extending get_confidence_measure_bank() and updating method-name selection in ConfidenceMethodMixin._init_confidence_method().

Changes:

  • Added new confidence measures: margin, max_prob_raw, top3_mass, and a new Shannon-style entropy entry in the measure bank.
  • Expanded supported method names and updated _init_confidence_method() branching to recognize the new options.
  • Updated ConfidenceMethodConfig documentation for some (but not all) newly supported method names.
File summaries
File Description
nemo/collections/asr/parts/utils/asr_confidence_utils.py Adds new confidence measure implementations and updates method-name routing to enable selecting them via config.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 6
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +241 to +244
# margin: p_max - p_second (top-2 gap, no V-normalization)
confidence_measure_bank["margin"] = lambda x, v, t: (
x.topk(2, dim=-1)[0][..., 0].exp() - x.topk(2, dim=-1)[0][..., 1].exp()
)
Comment on lines +245 to +248
# max_prob_raw: raw softmax probability (no V-normalization)
confidence_measure_bank["max_prob_raw"] = lambda x, v, t: (
x.max(dim=-1)[0].exp() if t == 1.0 else (x.max(dim=-1)[0] * t).exp()
)
Comment on lines +269 to +270
# top3_mass: sum of top-3 softmax probabilities, in [0, 1]
confidence_measure_bank["top3_mass"] = lambda x, v, t: (torch.softmax(x * t, dim=-1).topk(3, dim=-1)[0].sum(-1))
Comment on lines +271 to +278
# entropy: 1 - H(p)/log(V), normalized Shannon entropy confidence in [0, 1]
confidence_measure_bank["entropy"] = lambda x, v, t: (
1.0
+ (torch.nn.functional.log_softmax(x * t, dim=-1).exp() * torch.nn.functional.log_softmax(x * t, dim=-1)).sum(
-1
)
/ math.log(v)
)
Comment on lines 341 to 345
elif confidence_method_cfg.name == "entropy":
measure_name = '_'.join(
[confidence_method_cfg.name, confidence_method_cfg.entropy_type, confidence_method_cfg.entropy_norm]
)
measure_name = "entropy"
elif confidence_method_cfg.name == "entropy_renyi_exp":
measure_name = "entropy_renyi_exp"
else:
Comment on lines 54 to 61
Args:
name: The method name (str).
Supported values:
- 'max_prob' for using the maximum token probability as a confidence.
- 'max_prob_raw' for the raw softmax probability (no V-normalization).
- 'margin' for the difference between top-2 probabilities (p_max - p_second).
- 'entropy' for using a normalized entropy of a log-likelihood vector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants