Repository navigation
Conversation
ngxson
requested changes
Oct 20, 2026
ngxson
left a comment
Collaborator
There was a problem hiding this comment.
the whole PR can be just 2 lines fix. see existing code before coding anything
hparams.ffn_op = FFN_GELU;
log_ffn_op = "gelu";
Collaborator
|
see #30852 |
Member
|
Thanks for finding the inconsistency! |
Contributor
Author
|
No problem! I will keep the code tighter for next fixes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
The Gemma 4 vision encoder (
PROJECTOR_TYPE_GEMMA4V) runs its MLP withgelu_quick, but the model'svision_config.hidden_activationisgelu_pytorch_tanh(same in the E2B, E4B, 26B-A4B and 31B configs).clip.cppfalls back toFFN_GELU_QUICKwhen an mmproj has neitheruse_gelunoruse_silu.Gemma4VisionAudioModelinconversion/gemma.pydoesn't write either key, so Gemma 4 vision mmproj files without the key getgelu_quick. Gemma 3 writesuse_geluin its converter, so it isn't affected.On photos the image embeddings drift from transformers: on E2B the worst image token has a cosine of 0.33. Running transformers with
quick_geluinstead reproduces llama.cpp's current output (mean cosine 0.99998 or higher on the 4 images I checked).Changes:
use_geluand raisesNotImplementedErrorfor any othervision_config.hidden_activation.clip_get_ffn_op(). ForGEMMA4Vfiles that have neitheruse_gelunoruse_siluit returnsFFN_GELU, so existing files work without reconversion. A key that is set is always honored, and other projectors behave as before.test-mtmd-implgetstest_clip_ffn_op, which checks the choice on synthetic GGUF metadata (no model needed). TheGEMMA4Vcase with no key fails without the fallback and passes with it.The converter also writes
use_geluintoGEMMA4UVfiles, butGEMMA4UVand the Gemma 4 audio encoder compute the same as before, because their graphs don't useffn_op.To reproduce:
python convert_hf_to_gguf.py google/gemma-4-E2B-it --remote --mmproj --outtype f32 --outfile mmproj-gemma-4-E2B-it-F32.gguftools/mtmd/test-1.jpeg(640x488) becomes 912x672 with the defaultmax_soft_tokens=280, which is 266 image tokens:python -c "from PIL import Image; Image.open('tools/mtmd/test-1.jpeg').resize((912, 672), Image.BICUBIC).save('img.png')"MTMD_DEBUG_EMBEDDINGS=out.bin llama-mtmd-cli -hf ggml-org/gemma-4-E2B-it-GGUF:Q8_0 --mmproj mmproj-gemma-4-E2B-it-F32.gguf --image img.png --image-min-tokens 266 --image-max-tokens 266 --jinja -p "Describe this image." -n 1On that image (266 tokens):
The old file and the reconverted file give byte-identical embeddings with this PR.
Additional information
Per-token cosine against transformers fp32 on E2B (
max_soft_tokens=280), 7 images resized to the transformers size. llama.cpp and transformers produce the same token count on all 7, so only the encoder differs:google/gemma-4-E2B-itI only measured E2B. The other sizes have the same vision activation and take the same path.
Checks: CPU build with the
ci/run.shflags in Debug and Release (LLAMA_FATAL_WARNINGS=ON, no warnings),ctest -L mainin both with theci/run.shexclusions (test-optandtest-llama-archsin Debug,test-optin Release;test-tokenizers-ggml-vocabsfails locally only because git-lfs isn't installed), flake8 and ty onconversion/gemma.py(no new diagnostics), and editorconfig-checker.Requirements