Skip to content

model : add H2O-Lightning-4B decision model - #30361

Merged
ngxson merged 6 commits into
ggml-org:masterfrom
pseudotensor:h2o-lightning-decision
Oct 20, 2026
Merged

ngxson merged 6 commits into
ggml-org:masterfrom
pseudotensor:h2o-lightning-decision

Conversation

@pseudotensor

@pseudotensor pseudotensor commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Adds a decision type for H2O-Lightning-4B (https://huggingface.co/h2oai/h2o-lightning-4b), a Qwen3.5-4B fine-tune that answers typed decisions with calibrated probabilities. With this, llama-server serves it on /v1/systemone directly, without our Python shim.

I tried the existing types first. The closest, openjev, gets the same accuracy but differs on 4/231 answers and by up to 0.33 in probability. Our model answers with " A" rather than "A", uses up to 255 labels, and expects Python-style JSON in the prompt (12.0 stays 12.0).

The converter reads the model's serve_config.json and refuses to write a GGUF if it doesn't match what the code expects.

Additional information

Checked against our reference implementation on 231 public decision tasks: all answers match, max probability difference 2.4e-6 (BF16 and Q8_0). Images: 30/30. Prompts are byte-identical except for non-NFC input.

The tests need a small random-weight test model (Apache-2.0, 46 MB). Until it is hosted they skip.

Two small related changes are on separate branches and can be separate PRs if wanted: an optional noul_floor request field, and a fix so /v1/systemone respects --no-cache-prompt.

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES. I used Claude to help write and test the code. I reviewed the changes and can answer questions on them.

Adds the h2o-lightning decision type for h2oai/h2o-lightning-4b
(Qwen3.5-4B with a merged decision LoRA).

None of the existing types match this model. It answers with " A"
rather than "A", uses up to 255 labels, and was trained on Python
json.dumps text, so floats like 12.0 must render as 12.0.

The converter writes the decision metadata and the systemone template
from the model's serve_config.json and refuses a config that doesn't
match. Tests skip unless the tiny test model is available locally.

Assisted-by: Claude Opus 5.5
@pseudotensor
pseudotensor requested review from a team and CISC as code owners October 12, 2026 00:02
@github-actions github-actions Bot added documentation Improvements or additions to documentation server conversion labels Oct 12, 2026
@ggml-gh-bot

ggml-gh-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown

Hi @pseudotensor, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@ggml-gh-bot ggml-gh-bot Bot added the draft PR will be changed to draft by github-actions bot label Oct 12, 2026
@github-actions
github-actions Bot marked this pull request as draft October 12, 2026 00:08
@github-actions github-actions Bot removed the draft PR will be changed to draft by github-actions bot label Oct 12, 2026
@pseudotensor
pseudotensor marked this pull request as ready for review October 12, 2026 03:22
@ngxson ngxson self-assigned this Oct 12, 2026
@ngxson

ngxson commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

there are quite some redundant changes here, I'll have a look a bit later. will push my clean up directly to this PR

@ngxson
ngxson requested a review from ggerganov as a code owner October 12, 2026 13:49
@ngxson

ngxson commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

should be good for review now

I put labels to a dedicated gguf metadata, hence the newly-added API in llama-ext.h. future models should use it instead of hard-coding labels into cpp code

@sandrohanea

sandrohanea commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Hello @pseudotensor ,
I recently added the NPC normalization: #30390

I see that you mentioned in https://huggingface.co/h2oai/h2o-lightning-4b-gguf#differences-from-the-shim that llama.cpp tokenizes the text as sent but the shim is using NPC normalization.

If you want, feel free to use the NPC normalizer using tokenizer.ggml.normalizer.nfc to llama.cpp as well.

You can add it on the set_vocab with:

self.gguf_writer.add_normalizer_nfc(True)

@CISC

CISC commented Oct 14, 2026

Copy link
Copy Markdown
Member

I see that you mentioned in https://huggingface.co/h2oai/h2o-lightning-4b-gguf#differences-from-the-shim that llama.cpp tokenizes the text as sent but the shim is using NFC normalization.

Ah, good observation, thank you!

@CISC

CISC commented Oct 14, 2026

Copy link
Copy Markdown
Member

@pseudotensor / @sandrohanea Since this is actually using the regular vocab mechanism it doesn't need to hardcode this, I will add support for detecting it in SpecialVocab in a separate PR.

@CISC

CISC commented Oct 14, 2026

Copy link
Copy Markdown
Member

@sandrohanea Someone needs to add NFC to the other tokenizers (this model is not UGM) though, want to do a PR?

@sandrohanea

Copy link
Copy Markdown
Contributor

@sandrohanea Someone needs to add NFC to the other tokenizers (this model is not UGM) though, want to do a PR?

Hello @CISC ,
I created: #30708 that will add support for NFC to all tokenizers.
However, I cannot send it as a PR as I reached my limit of 2 open PRs :D

image

@pseudotensor

Copy link
Copy Markdown
Contributor Author

@CISC done.

@pseudotensor

Copy link
Copy Markdown
Contributor Author

@sandrohanea Are you able to approve workflows?

@ngxson
ngxson merged commit 7e3eeee into ggml-org:master Oct 20, 2026
21 checks passed
cursor Bot pushed a commit to gianlucamazza/xllama that referenced this pull request Oct 24, 2026
… fails load on d812350)

Owner-approved validation spike: prefill + softmax over candidate label
tokens, no generation on the decider path, no llama.cpp bump and no
cherry-pick of ggml-org/llama.cpp#30361.

Stock-Q4_K_M is qwen35 but does not load on pin d812350:
check_tensor_dims reports missing blk.32.attn_norm.weight (metadata
claims MTP; the file has trunk blk.0-blk.31 only). Labels are read from
GGUF KV via the gguf API. The prompt mirrors #30361 (Answer: prefill,
leading-space labels, JSON options, 32k state cut, 255 options).
Multi-token labels use the first token — a known limitation vs the
upstream shim. 204/231 stays vendor-claimed; Series S cells pending.

Co-authored-by: Gianluca Mazza <gianlucamazza@users.noreply.github.com>
auRose94 pushed a commit to auRose94/llama.cpp that referenced this pull request Oct 28, 2026
* model : add H2O-Lightning-4B decision model

Adds the h2o-lightning decision type for h2oai/h2o-lightning-4b
(Qwen3.5-4B with a merged decision LoRA).

None of the existing types match this model. It answers with " A"
rather than "A", uses up to 255 labels, and was trained on Python
json.dumps text, so floats like 12.0 must render as 12.0.

The converter writes the decision metadata and the systemone template
from the model's serve_config.json and refuses a config that doesn't
match. Tests skip unless the tiny test model is available locally.

Assisted-by: Claude Opus 5.5

* rm redundant code

* put labels to gguf

---------

Co-authored-by: Jonathan C. McKinney <jon.mckinney@h2o.ai>
Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conversion documentation Improvements or additions to documentation server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants