Skip to content

mtmd: test that every projector is registered and uniquely named - #176

Open
danielhanchen wants to merge 2 commits into
base/upstream-9a4843cf2from
mtmd-projector-registry-test
Open

mtmd: test that every projector is registered and uniquely named#176
danielhanchen wants to merge 2 commits into
base/upstream-9a4843cf2from
mtmd-projector-registry-test

Conversation

@danielhanchen

Copy link
Copy Markdown
Member

Nothing checks the projector registry, and it needs no model file to check. That matters for the nightly: every vision and audio tower we pin (kimik3, inkling, glm5next) is registered by hand in the same two places, and a merge that loses one of those lines compiles.

What breaks without it

Two shapes, both of which compile, neither visible until someone loads a model.

A projector's enum value survives while its PROJECTOR_TYPE_NAMES entry is lost. clip_projector_type_from_string then returns PROJECTOR_TYPE_UNKNOWN for it, and every model using that tower fails to load with no indication why. Deleting the PROJECTOR_TYPE_KIMIK25 line:

ASSERT EQUAL FAILED : projector 46 has a name
  expected: named
  actual  : missing from PROJECTOR_TYPE_NAMES

Two projectors end up sharing a name, which silently routes one model to the other's graph. Repointing PROJECTOR_TYPE_GLM4V at "kimik25":

ASSERT EQUAL FAILED : "kimik25" resolves to its own projector
  expected: 46
  actual  : 43
ASSERT EQUAL FAILED : "kimik25" names exactly one projector
  expected: unique
  actual  : also names projector 43

The test

Walks the enum, and per value asserts it has a name, that the name resolves back through the same lookup a model load goes through rather than by reading the table backwards, and that no name is claimed twice. Plus one assertion that an unregistered string still lands on UNKNOWN, since clip reads that string straight out of the GGUF and a typo must not become a wrong graph.

185 assertions, no I/O, runs in the existing test-mtmd-impl registry.

The one exemption

PROJECTOR_TYPE_MLP_NORM has no name and correctly so: clip assigns it from the tensor shapes for Yi-type llava (clip.cpp, "this is a hack to support Yi-type llava") and never reads it from a file, so it is unnameable by construction rather than by omission.

It is listed in an internal_only set with that reason rather than the assertion being weakened, because the two cases look identical from the outside and only one of them is fine. The comment says what adding a second entry would mean: a projector no model can ever select.

Found by running the test, incidentally, which is the first thing it did.

Notes

Generic, no Unsloth specifics, and worth sending to ggml-org as-is. It sits on base/upstream-67a17c17c (b10775 verbatim) so it can be pinned in the meantime, which is how the nightly gets it before upstream takes it.

$ ./build/bin/test-mtmd-impl
test_image_preprocessor_lfm2 (5 assertion(s))    [PASS]
test_temporal_merge_grouping (24 assertion(s))   [PASS]
test_projector_registry (185 assertion(s))       [PASS]

tests      : 3
assertions : 214
failures   : 0

Nothing checks the projector registry, and it needs no model file to check.

Two ways it breaks, both of which compile and neither of which is visible
until someone loads a model:

  * a projector's enum value survives an edit while its PROJECTOR_TYPE_NAMES
    entry is lost. clip_projector_type_from_string then returns
    PROJECTOR_TYPE_UNKNOWN for it, and every model using that tower fails to
    load with no indication of why.
  * two projectors end up sharing a name, which routes one model to the
    other's graph. Deleting one line to demonstrate:

      { PROJECTOR_TYPE_GLM4V, "kimik25"}

      ASSERT EQUAL FAILED : "kimik25" resolves to its own projector
        expected: 46
        actual  : 43

So: walk the enum, and for each value assert it has a name, that the name
resolves back through the same lookup a model load goes through, and that no
name is claimed twice. Also assert an unregistered string still lands on
UNKNOWN, since clip reads that string straight out of the GGUF and a typo must
not become a wrong graph.

PROJECTOR_TYPE_MLP_NORM is exempt and listed as such: clip assigns it from the
tensor shapes for Yi-type llava and never reads it from a file, so it is
unnameable by construction rather than by omission. It is the only one, and
the comment says what adding a second would mean.

185 assertions, no I/O.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T11:42:28.158180Z 09ce1a4 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ad7512711

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/test-mtmd-impl.cpp
Comment on lines +149 to +152
// A projector whose enum value survives a merge while its PROJECTOR_TYPE_NAMES
// entry is lost still compiles, and every model using it then loads as
// PROJECTOR_TYPE_UNKNOWN. Two projectors sharing a name compiles too, and
// silently routes one model to the other's graph.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Condense the projector registry comments

This explanation hard-wraps sentences across four source lines and, together with the adjacent comment blocks, adds extensive narration for straightforward assertions. The repository explicitly requires concise comments, avoids excessive commentary, and prohibits splitting sentences across lines; condense this to one or two simple lines without mid-sentence wrapping.

AGENTS.md reference: AGENTS.md:L74-L81

Useful? React with 👍 / 👎.

@danielhanchen
danielhanchen requested a review from CISC as a code owner September 4, 2026 11:39
@danielhanchen
danielhanchen changed the base branch from base/upstream-67a17c17c to base/upstream-9a4843cf2 September 4, 2026 11:39
@danielhanchen
danielhanchen changed the base branch from base/upstream-9a4843cf2 to master September 4, 2026 11:39
@danielhanchen
danielhanchen changed the base branch from master to base/upstream-9a4843cf2 September 4, 2026 11:40
danielhanchen added a commit that referenced this pull request Sep 4, 2026
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