Skip to content

fix: a skill with huge dialog files can no longer crash classifier training - #31

Merged
mikejgray merged 1 commit into
mainfrom
fix/dialog-lines-cap
Oct 15, 2026
Merged

mikejgray merged 1 commit into
mainfrom
fix/dialog-lines-cap

Conversation

@mikejgray

Copy link
Copy Markdown
Contributor

The bug

Installing ovos-skill-days-in-history stops Switchboard's classifier from ever becoming ready. The training child dies with SIGBUS, and the log shows "classifier training child exited with -10".

The skill ships 136,639 dialog lines, one per historical event. Switchboard trains its "not for me" class on every installed skill's spoken lines, which took the training set from about 36k rows and 21k features to 175k rows and 821k features. Logistic regression keeps a weight per feature per class, and SciPy's L-BFGS-B keeps 10 update pairs of that vector, indexed with 32-bit integers: 2 × 10 × 821k × 166 = 2.7 billion, past 2,147,483,647. Both crash reports fault at the identical address.

The crash reproduces outside OVOS, with SciPy 1.17.1 and 1.18.1. It isn't caused by launchd or by forking: the child is spawned and had 2 threads when it crashed.

The fix

  • dialog_negatives_exclude (classifier setting), defaulting to ["ovos-skill-days-in-history.openvoiceos"]. Those lines are data, not phrasing, and the echo step already handles the assistant hearing itself.
  • At most 2,000 spoken lines per package, sampled evenly and deterministically, as a guard for data-heavy skills nobody has listed. The largest ordinary skill measured had 1,643 lines (dad jokes), so setups like the measured ones keep every line.
  • options_from now turns config lists into tuples for tuple-typed settings.

Checks

  • On the crashing install, with the new default: 39k rows, trains.
  • On the crashing install, with the cap alone: 41k rows, workspace 355M, trains.
  • check_harness: 8/8 identical. 142 tests pass (4 new); ruff and pylint are clean.

Still open: the fit isn't bounded against inputs in general. Bounding the vocabulary (min_df or max_features) would be, but it changes the trained model, so it needs its own harness run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KjZYoJmprjrVro214krcYK

…aining

ovos-skill-days-in-history ships 136,639 dialog lines, one per historical
event. Every line became a "not for me" training row, so installing it took
the classifier from about 36k rows and 21k features to 175k rows and 821k
features. The fit then overflowed SciPy's L-BFGS-B work array (2 x 10 x
features x classes = 2.7 billion, past the 32-bit index limit), the
training child died with SIGBUS, and the classifier never became ready.

- dialog_negatives_exclude (default: days-in-history) leaves a skill's
  dialog lines out.
- Each package contributes at most 2,000 spoken lines, sampled evenly and
  deterministically, as a guard for skills nobody has listed. The largest
  ordinary skill measured had 1,643, so setups like the measured ones keep
  every line.
- options_from now turns config lists into tuples for tuple settings.

Checked on the crashing install: with the default it trains on 39k rows;
with the cap alone, 41k rows (2mn = 355M). check_harness: 8/8 identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KjZYoJmprjrVro214krcYK
@mikejgray
mikejgray merged commit 82d39dc into main Oct 15, 2026
@mikejgray
mikejgray deleted the fix/dialog-lines-cap branch October 15, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant