Skip to content

model: Add support for SenseNova U1 model - #28919

Merged
ngxson merged 18 commits into
ggml-org:masterfrom
Maphist0:dev-u1
Oct 21, 2026
Merged

ngxson merged 18 commits into
ggml-org:masterfrom
Maphist0:dev-u1

Conversation

@Maphist0

Copy link
Copy Markdown
Contributor

Overview

This PR adds support for the SenseNova U1 text-generation branch in llama.cpp.

Supported use cases:

  • Text-to-text generation
  • Image-to-text generation
  • Image-plus-text-to-text generation

The image path supports SenseNova U1’s dynamic-resolution preprocessing, 2D RoPE, patch embedding, spatial merge, and image-token injection.

The implementation is intentionally limited to U1’s understanding/text-generation branch. Image generation branch is not included.

Additional information

Related to discussion #23529

Validation

Compile:

cmake -B build-u1-cuda \
  -DGGML_CUDA=ON \
  -DCMAKE_CUDA_ARCHITECTURES=90-real \
  -DLLAMA_BUILD_SERVER=ON \
  -DCMAKE_BUILD_TYPE=Release

cmake --build build-u1-cuda -j8 \
  --target llama-cli llama-completion llama-mtmd-cli

Convert ckpt:

python convert_hf_to_gguf.py \
  <official_u1_ckpt_path> \
  --outtype bf16 \
  --outfile SenseNova-U1.5-8B-bf16.gguf

python convert_hf_to_gguf.py \
  <official_u1_ckpt_path> \
  --mmproj \
  --outtype bf16 \
  --outfile SenseNova-U1.5-8B-mmproj-bf16.gguf

Case 1: Text generation:

build-u1-cuda/bin/llama-cli \
  -m SenseNova-U1.5-8B-bf16.gguf \
  --single-turn \
  -p <YOUR_PROMPT> \
  -n 128 \
  --temp 0 \
  --seed 0 \
  -ngl all \
  -c 4096

Case 2: Image-to-text generation:

build-u1-cuda/bin/llama-cli \
  -m SenseNova-U1.5-8B-bf16.gguf \
  -mm SenseNova-U1.5-8B-mmproj-bf16.gguf \
  --image test-image.jpg \
  --single-turn \
  -p <YOUR_PROMPT> \
  -n 128 \
  --temp 0 \
  --seed 0 \
  -ngl all \
  --mmproj-offload \
  -c 4096 \
  --no-display-prompt \
  --no-show-timings

Case 3: Image-text-to-text generation:

build-u1-cuda/bin/llama-cli \
  -m SenseNova-U1.5-8B-bf16.gguf \
  -mm SenseNova-U1.5-8B-mmproj-bf16.gguf \
  --image test-image.jpg \
  --single-turn \
  -p <YOUR_PROMPT> \
  -n 128 \
  --temp 0 \
  --seed 0 \
  -ngl all \
  --mmproj-offload \
  -c 4096 \
  --no-display-prompt \
  --no-show-timings

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES. I've used GPT 5.5 for majority of code generation under my review. Code generated by AI was reviewed before adding into the codebase.

Add support for the dense SenseNova U1 understanding branch, including
the U1.5-8B-MoT model.

- Add HF-to-GGUF conversion for NEOChatModel, excluding MoT generation
  tensors and concatenating temporal and spatial Q/K normalization
  weights.
- Register the sensenova_u1 GGUF architecture and custom spatial RoPE
  metadata.
- Implement temporal/spatial Q/K normalization with 4-axis RoPE.
- Keep U1-specific text position handling in the model implementation.
- Add synthetic architecture coverage for sensenova_u1.

Only the dense understanding branch is supported; generation
branches are intentionally rejected during conversion.
Add conversion support for the SenseNova U1 vision encoder and implement
its CPU mtmd projector graph.

The graph applies patch embedding, GELU, adjacent-pair 2D RoPE, spatial
downsampling, and dense projection for dynamic-resolution image inputs.
@github-actions github-actions Bot added model Model specific testing Everything test related mtmd Related to multimodal functionality (video/image/audio) conversion labels Sep 15, 2026

@ngxson ngxson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

for vision support: mirror what gemma4uv.cpp is doing. keep it simple.

Comment thread conversion/sensenova_u1.py Resolved
Comment thread conversion/sensenova_u1.py Resolved
Comment thread src/models/sensenova-u1.cpp Resolved
Comment thread tests/test-llama-archs.cpp Resolved
Comment thread tools/mtmd/clip-impl.h Resolved
Replace the hard-coded spatial RoPE key with shared GGUF and LLM_KV
definitions used by conversion, model loading, and architecture tests.

Clarify why SenseNova U1 retains its custom text-position input: U1 uses
[t, 0, 0, 0], while the generic M-RoPE input uses [t, t, t, 0].
Map the SenseNova U1 dense projection to the standard mm.0 weight and
bias tensors and reuse the shared projector fields in the loader and graph.

Read vision parameters from the checkpoint configuration and remove the
U1-specific tensor names and model fields while preserving its strided
projection, bias, and row-major token layout.
@Maphist0
Maphist0 requested a review from ngxson September 22, 2026 08:57
@Maphist0

Copy link
Copy Markdown
Contributor Author

@ngxson Thank you for the constructive feedback. I’ve updated the patches to address the review comments and look forward to further discussion.

@ngxson ngxson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

mtmd part is ok

@Maphist0

Copy link
Copy Markdown
Contributor Author

mtmd part is ok

Many thanks!

Would other reviewers (@CISC @ggerganov @JohannesGaessler) please also take a look and make some review comments when available? That would be very helpful!

Comment thread conversion/sensenova_u1.py Resolved
Comment thread src/models/sensenova-u1.cpp Resolved
Comment thread src/models/sensenova-u1.cpp Resolved
Comment thread src/models/sensenova-u1.cpp Resolved
@CISC
CISC removed the request for review from JohannesGaessler October 20, 2026 12:54
Maphist0 and others added 3 commits October 20, 2026 21:01
Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
Use standard backend precision handling for QKV, FFN, and output
projections instead of casting inputs based on the output tensor type.

Assisted-by: Codex
@Maphist0
Maphist0 requested a review from CISC October 20, 2026 15:54
@Maphist0

Copy link
Copy Markdown
Contributor Author

@CISC Thank you very much for the constructive comments. I’ve updated the patches to address them and look forward to further discussion.

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
@CISC CISC added the merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. label Oct 21, 2026
@ngxson
ngxson merged commit 7775ffb into ggml-org:master Oct 21, 2026
27 of 37 checks passed
@Maphist0
Maphist0 deleted the dev-u1 branch October 21, 2026 23:29
@wmx-github

This comment was marked as low quality.

auRose94 pushed a commit to auRose94/llama.cpp that referenced this pull request Oct 28, 2026
* model : add SenseNova U1 understanding support

Add support for the dense SenseNova U1 understanding branch, including
the U1.5-8B-MoT model.

- Add HF-to-GGUF conversion for NEOChatModel, excluding MoT generation
  tensors and concatenating temporal and spatial Q/K normalization
  weights.
- Register the sensenova_u1 GGUF architecture and custom spatial RoPE
  metadata.
- Implement temporal/spatial Q/K normalization with 4-axis RoPE.
- Keep U1-specific text position handling in the model implementation.
- Add synthetic architecture coverage for sensenova_u1.

Only the dense understanding branch is supported; generation
branches are intentionally rejected during conversion.

* conversion : treat one-expert SenseNova U1 configs as dense

* mtmd : add SenseNova U1 vision support

Add conversion support for the SenseNova U1 vision encoder and implement
its CPU mtmd projector graph.

The graph applies patch embedding, GELU, adjacent-pair 2D RoPE, spatial
downsampling, and dense projection for dynamic-resolution image inputs.

* mtmd : fix SenseNova U1 vision token layout

* model : clean up SenseNova U1 RoPE metadata

Replace the hard-coded spatial RoPE key with shared GGUF and LLM_KV
definitions used by conversion, model loading, and architecture tests.

Clarify why SenseNova U1 retains its custom text-position input: U1 uses
[t, 0, 0, 0], while the generic M-RoPE input uses [t, t, t, 0].

* mtmd : simplify SenseNova U1 projector integration

Map the SenseNova U1 dense projection to the standard mm.0 weight and
bias tensors and reuse the shared projector fields in the loader and graph.

Read vision parameters from the checkpoint configuration and remove the
U1-specific tensor names and model fields while preserving its strided
projection, bias, and row-major token layout.

* mtmd : fix SenseNova U1 image positions and attention

* fix spacing

* mtmd : restore generic test input chunks

* mtmd : restore SenseNova U1 integration after upstream merge

* Update conversion/sensenova_u1.py

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>

* Update src/models/sensenova-u1.cpp

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>

* model : remove SenseNova U1 BF16 activation casts

Use standard backend precision handling for QKV, FFN, and output
projections instead of casting inputs based on the output tensor type.

Assisted-by: Codex

* Update src/models/sensenova-u1.cpp

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>

---------

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@huggingface.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conversion merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. model Model specific mtmd Related to multimodal functionality (video/image/audio) testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants