Skip to content

add Qwen3 VL tests, update logit checker, and golden logit generator#4330

Merged
copybara-service[bot] merged 1 commit into
mainfrom
update-logit-checker
Jul 10, 2026
Merged

add Qwen3 VL tests, update logit checker, and golden logit generator#4330
copybara-service[bot] merged 1 commit into
mainfrom
update-logit-checker

Conversation

@subawocit

@subawocit subawocit commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR adds logit checking and end-to-end integration validation support for Qwen3-VL models. It extends both the golden logit generation utility and the forward-pass logit checker to handle multimodal components for Qwen3-VL models. An end-to-end shell script was also added to compare MaxText logits with Hugging Face golden logits.

generate_hf_golden_logits.py

  • Supported loading Qwen3VLForConditionalGeneration model class for "qwen3-vl" model identifiers.
  • Added pixel values saving logic for Qwen3-VL models.

forward_pass_logit_checker.py

  • Added example useages following the discussion from PR 4310.
  • Added reshape logic for Qwen3 pixel values. Reshapes visual patches from flat layout back to the 4D shape (channels, time * temporal_patch_size, height * patch_size, width * patch_size).
  • Added 3D position ID generation (M-RoPE index) via processor_qwen3_omni.get_rope_index when use_mrope is enabled for Qwen3 models.
  • Added masking for vision placeholder tokens (vision_start, vision_end, image_pad, video_pad) during KL divergence calculation. Since the model is not trained to predict next token from raw vision placeholders, their logits can be random and vary numerically. Masking them prevents visual placeholders from skewing the max KL divergence score, and focuses the comparison on actual language-generation logits.
  • Improved output log readability (See comment below)

test_qwen3_vl_2b_to_hf_e2e.sh

  • Added tests/end_to_end/tpu/qwen3/vl_2b/test_qwen3_vl_2b_to_hf_e2e.sh following test_gemma4_to_hf.sh:
    1. Converts Qwen3-VL-2B-Instruct Hugging Face original checkpoint to Maxtext.
    2. Converts Qwen3-VL-2B-Instruct MaxText checkpoint to Hugging Face format.
    3. Generates golden logits using the original HF Qwen3-VL-2B-Instruct model for comparison.
    4. Runs the forward pass logit checker to verify that whether the MaxText model's outputs closely match the HF golden logits within the specified KL divergence threshold (--max_kl_div=0.1).

Tests

Define variables: HF_TOKEN, MODEL_BUCKET, LOCAL_PATH, USE_MULTIMODAL, USE_SCAN_LAYERS in tests/end_to_end/tpu/qwen3/vl_2b/test_qwen3_vl_2b_to_hf_e2e.sh

bash tests/end_to_end/tpu/qwen3/vl_2b/test_qwen3_vl_2b_to_hf_e2e.sh

Test Results

Text-only input (USE_MULTIMODAL=false)
INFO:absl:[process=0] [sync] Finished load in 8.83 seconds @ gs://yuchenhou-maxtext-logs/checkpoints/qwen3-vl-2b/unscanned/2026-07-01-18-23/0/items
INFO:absl:
--- Prompt: I love to ---
INFO:absl:
--- MaxText model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 8180       | eat                  | 22.5420    |
| 1349       | read                 | 22.3564    |
| 4296       | cook                 | 22.0374    |
| 728        | go                   | 21.8470    |
| 1486       | play                 | 21.8353    |
| 3270       | write                | 21.8291    |
| 5821       | travel               | 21.7823    |
| 3736       | watch                | 21.6665    |
| 13186      | explore              | 21.5567    |
| 1281       | make                 | 21.5405    |

INFO:absl:
--- HF model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 8180       | eat                  | 22.5487    |
| 1349       | read                 | 22.3641    |
| 4296       | cook                 | 22.0673    |
| 1486       | play                 | 21.8461    |
| 728        | go                   | 21.8436    |
| 3270       | write                | 21.8413    |
| 5821       | travel               | 21.8039    |
| 3736       | watch                | 21.6521    |
| 13186      | explore              | 21.5848    |
| 1281       | make                 | 21.5531    |

INFO:absl:
--- Similarity Metrics of Top Tokens ---
INFO:absl:| Metric                         | Value                |
|--------------------------------|----------------------|
| overlap_count                  | 10/10                |
| jaccard_similarity             | 1.0                  |
| rank_agreement_percentage      | 80.0                 |

INFO:absl:
Average KL divergence per token (D_KL(P_golden || Q_model)): 1.0004e-04
INFO:absl:Per-token KL Divergences: 
['2.0459e-04', '4.0602e-05', '5.4927e-05']
INFO:absl:
Max KL divergence for a single token in the set: 2.0459e-04
INFO:absl:
--- Prompt: Today is a ---
INFO:absl:
--- MaxText model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 3281       | special              | 20.7137    |
| 1661       | good                 | 20.4657    |
| 7270       | Sunday               | 20.2309    |
| 13257      | holiday              | 20.2303    |
| 1602       | very                 | 20.1504    |
| 6602       | Friday               | 20.1455    |
| 1899       | day                  | 20.1153    |
| 7728       | Saturday             | 20.0202    |
| 39698      | sunny                | 19.8981    |
| 7014       | Monday               | 19.8644    |

INFO:absl:
--- HF model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 3281       | special              | 20.6899    |
| 1661       | good                 | 20.4342    |
| 13257      | holiday              | 20.2157    |
| 7270       | Sunday               | 20.2105    |
| 6602       | Friday               | 20.1267    |
| 1602       | very                 | 20.1233    |
| 1899       | day                  | 20.0998    |
| 7728       | Saturday             | 19.9995    |
| 39698      | sunny                | 19.8598    |
| 7014       | Monday               | 19.8466    |

INFO:absl:
--- Similarity Metrics of Top Tokens ---
INFO:absl:| Metric                         | Value                |
|--------------------------------|----------------------|
| overlap_count                  | 10/10                |
| jaccard_similarity             | 1.0                  |
| rank_agreement_percentage      | 60.0                 |

INFO:absl:
Average KL divergence per token (D_KL(P_golden || Q_model)): 7.7883e-04
INFO:absl:Per-token KL Divergences: 
['2.1909e-03', '9.6892e-05', '4.8693e-05']
INFO:absl:
Max KL divergence for a single token in the set: 2.1909e-03
INFO:absl:
--- Prompt: What is the ---
INFO:absl:
--- MaxText model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 829        | name                 | 25.1269    |
| 3476       | role                 | 25.0997    |
| 1887       | main                 | 24.9784    |
| 7428       | purpose              | 24.9392    |
| 25361      | significance         | 24.6545    |
| 6028       | primary              | 24.2031    |
| 2265       | title                | 24.2027    |
| 6672       | difference           | 23.6845    |
| 5025       | relationship         | 23.6137    |
| 14806      | formula              | 23.4353    |

INFO:absl:
--- HF model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 829        | name                 | 25.1467    |
| 3476       | role                 | 25.1241    |
| 1887       | main                 | 24.9939    |
| 7428       | purpose              | 24.9528    |
| 25361      | significance         | 24.6584    |
| 2265       | title                | 24.2286    |
| 6028       | primary              | 24.2195    |
| 6672       | difference           | 23.7052    |
| 5025       | relationship         | 23.6169    |
| 14806      | formula              | 23.4388    |

INFO:absl:
--- Similarity Metrics of Top Tokens ---
INFO:absl:| Metric                         | Value                |
|--------------------------------|----------------------|
| overlap_count                  | 10/10                |
| jaccard_similarity             | 1.0                  |
| rank_agreement_percentage      | 80.0                 |

INFO:absl:
Average KL divergence per token (D_KL(P_golden || Q_model)): 1.2265e-03
INFO:absl:Per-token KL Divergences: 
['3.6423e-03', '5.0167e-06', '3.2072e-05']
INFO:absl:
Max KL divergence for a single token in the set: 3.6423e-03
Text and image input (USE_MULTIMODAL=true)
--- Comparing forward pass for golden data index: 0 ---
INFO:absl:config.global_batch_size_to_train_on=4
INFO:absl:pixel_values.shape = (1360, 1536)
INFO:absl: prompt="<|im_start|>user
<|vision_start|><|image_pad|><|vision_end|>Describe this image<|im_end|>
<|im_start|>assistant
" raw ids=[151644    872    198 151652 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151653  74785    419   2168 151645    198
 151644  77091    198], logits.shape = (353, 151936)
INFO:absl:maxtext forward pass
INFO:absl:
[logits: token 2]
INFO:absl:golden_logits_slice[2]=array([12.931317, 13.484477, 16.856901, ...,  1.990514,  1.990514,
        1.990514], dtype=float32)
INFO:absl:train_logits_slice[2]=array([12.94264 , 13.495019, 16.869377, ...,  1.988577,  1.988577,
        1.988577], dtype=float32)
INFO:absl:
[numerical difference]
Max absolute difference: 2.2326e+01 at index (Array(101, dtype=int32), Array(99488, dtype=int32))
  (Train: -8.6359e+00, Golden: 1.3690e+01)
Max relative difference: 7.1453e+05 at index (Array(102, dtype=int32), Array(147597, dtype=int32))
  (Train: -1.0222e+00, Golden: -1.4305e-06)
INFO:absl:
[probability: token 1]
INFO:absl:golden_probabilities[1]=Array([2.2498674e-09, 1.4269050e-11, 8.2976987e-07, ..., 1.1374250e-12,
       1.1374250e-12, 1.1374250e-12], dtype=float32)
INFO:absl:model_probabilities[1]=Array([2.2730862e-09, 1.4259688e-11, 8.3804821e-07, ..., 1.1365343e-12,
       1.1365343e-12, 1.1365343e-12], dtype=float32)
INFO:absl:
[KL divergence]
KL divergence = [1.0378430e-06 6.7985662e-10 6.8534757e-07 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00 0.0000000e+00
 1.9606786e-04 8.2948734e-04 1.1934385e-06 6.0532159e-14 2.3219182e-10
 3.2614307e-06 1.5081502e-08 3.3456541e-07], max KL divergence = 0.0008294873405247927 at index 346, the corresponding token id is 419
INFO:absl:Checking KL Divergence between train distribution and golden distribution against threshold 0.1.

Checklist

Before submitting this PR, please make sure (put X in square brackets):

  • I have performed a self-review of my code. For an optional AI review, add the gemini-review label.
  • I have necessary comments in my code, particularly in hard-to-understand areas.
  • I have run end-to-end tests tests and provided workload links above if applicable.
  • I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in our documentation.

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@hengtaoguo hengtaoguo 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.

Thanks for the great work!

Looking at the "Text and image input" logs in the PR description:

  1. Please try to improve the output logs readability.
  2. We don't need to print out the full token_ids and kl_divergence for the entire prompt, since prompt with image has relatively longer sequence length and it will flush the terminal.
  3. Print diff values in a consistent format. E.g. I saw both 2.2498674e-09 and 0.0008294873405247927. Maybe let's consolidate to two decimal representation like 2.24e-09
  4. Could you also print "top 10 tokens" for this one prompt's first generation, similar to the text-only input?

val_np = value.cpu().numpy()
data_to_save[new_key] = val_np[0] if val_np.ndim > 0 else val_np
if key == "pixel_values" and "qwen3-vl" in model_id.lower():
data_to_save[new_key] = val_np

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.

Could you remind me why this new branch is needed?

@subawocit subawocit Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Supported Gemma and Llama models' val_np has a dummy batch dimension of size 1, and val_np[0] was used to strip this batch dimension. But in Qwen3-VL models, the val_np is [num_patches, patch_dim], so val_np[0] would delete the entire image except for the first image patch. If-else statement was added to prevent this.


Note: For multimodal models, running the HuggingFace model on-the-fly inside this script is not supported.
You must pre-generate the HuggingFace golden logits file first using
tests/assets/logits_generation/generate_hf_golden_logits.py.

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.

Could you also provide a command example here to generate the hf logits?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated

image_path=tests/assets/test_image.jpg \
--max_kl_div=0.1 \
--golden_logits_path=golden_qwen2-vl-7b_vision.jsonl \
override_model_config=true

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.

Maybe merge some lines together to make this example command more condensed?

e.g.

python3 -m benchmarks.mmlu.mmlu_eval src/maxtext/configs/base.yml \
tokenizer_path=src/maxtext/assets/tokenizer_llama3.tiktoken \
load_parameters_path=check_point_path model_name=llama3.1-8b \
max_prefill_predict_length=1024 max_target_length=2048 ici_tensor_parallelism=4 per_device_batch_size=1 \
prompt_template="The following are multiple choice questions (with answers) about {subject}.\n\n{question}\n
{choices}\nAnswer: Let's think step by step."

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated

src/maxtext/configs/base.yml \
tokenizer_path=<your-bucket>/gemma-2-2b \
load_parameters_path=<your-bucket>/gemma-2-2b/maxtext_ckpt/0/items \
model_name=gemma-2-2b \

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.

Could you double check the model_name in maxtext? It looks like gemma2-2b is the correct spelling. Or we could use qwen3-0.6b as it's newer and smaller, also belong to the same model family as qwen3-vl.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed - the code now uses qwen3-0.6b

Comment on lines +263 to +264
else:
pixel_values = np.transpose(pixel_values, (1, 2, 0))

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.

Could you help me understand why this new else branch for transpose is needed? IIUC we are only updating for the qwen3 vision family.

@subawocit subawocit Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, these two lines are unnecessary, I just fixed the code

if jax.process_index() == 0 and test_args.output_logits_path:
data_to_save = {
"prompt": golden_data[golden_data_index]["prompt"],
"prompt": golden_data_point["prompt"],

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.

Make sure this change doesn't impact any other text-only models?

@subawocit subawocit Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Checked with Gemma 3 4B (text only input) and Gemma 2 2B. KL were all below threshold and no error detected

--output-path=${GOLDEN_LOGITS_PATH} \
--prompts="${TEST_PROMPT}" \
--image-paths=${TEST_IMAGE} \
--hf-model-path=${LOCAL_PATH} \

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.

Have you tried directly passing --hf-model-path=Qwen/Qwen3-VL-2B-Instruct to compare against the original HF model?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call - I just did and results look reasonable: max KL divergence = 0.0008294873405247927 at index 346, the corresponding token id is 419

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.

Great, I would recommend you to directly compare against HF model at this line instead of using LOCAL_PATH from the HF roundtrip conversion model.

As for the to_huggingface command, let's move it towards the end of this file. WDYT?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

SG - I just updated the file

@subawocit subawocit force-pushed the update-logit-checker branch 2 times, most recently from 0579310 to 356b09d Compare July 7, 2026 20:45
@subawocit

subawocit commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

To improve output readability, several code blocks were modified in forward_pass_logit_checker.py.

  1. Updated numerical formatting to consistently be :.2e
  2. Truncated raw outputs:
    • Removed raw per-token KL divergence number from Line 461 in old code and only show summary statistics
    • Only show first 20 raw token ID
  3. Moved up the tokenizer initialization block from text-only-input branch in Line 537 in old code, such that the tokenizer can be used for both pre-loaded golden logits comparison (multimodal input) and on-the-fly HuggingFace model comparison (text-only input), which is necessary for top-k token prediction comparison.
  4. Added Top-10 token prediction comparison table for multimodal input using compare_top_tokens.

Test Result

Updated Text and image input (USE_MULTIMODAL=true) using Qwen3-VL-2B

Qwen3 VL 2B

--- Comparing forward pass for golden data index: 0 ---
INFO:absl:config.global_batch_size_to_train_on=4
INFO:absl:pixel_values.shape = (1360, 1536)
INFO:absl: prompt="<|im_start|>user
<|vision_start|><|image_pad|><|vision_end|>Describe this image<|im_end|>
<|im_start|>assistant
" raw ids (first 20)=[151644    872    198 151652 151655 151655 151655 151655 151655 151655
 151655 151655 151655 151655 151655 151655 151655 151655 151655 151655], logits.shape = (353, 151936)
INFO:absl:maxtext forward pass
INFO:absl:
[logits: token 2]
INFO:absl:golden_logits_slice[2]=array([12.931317, 13.484477, 16.856901, ...,  1.990514,  1.990514,
        1.990514], dtype=float32)
INFO:absl:train_logits_slice[2]=array([12.94264 , 13.495019, 16.869377, ...,  1.988577,  1.988577,
        1.988577], dtype=float32)
INFO:absl:
[numerical difference]
Max absolute difference: 2.23e+01 at index (Array(101, dtype=int32), Array(99488, dtype=int32))
  (Train: -8.64e+00, Golden: 1.37e+01)
Max relative difference: 7.15e+05 at index (Array(102, dtype=int32), Array(147597, dtype=int32))
  (Train: -1.02e+00, Golden: -1.43e-06)
INFO:absl:
--- MaxText model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 1986       | This                 | 36.7500    |
| 2124       | Of                   | 32.6982    |
| 28715      | Based                | 30.5784    |
| 785        | The                  | 29.3722    |
| 8420       | Here                 | 26.2462    |
| 95456      | Certainly            | 25.8872    |
| 32313      | Okay                 | 24.6171    |
| 2082       | An                   | 24.5233    |
| 1096       | This                 | 24.3942    |
| 43288      | 这                    | 24.0502    |

INFO:absl:
--- HF model top 10 tokens ---
INFO:absl:| Token ID   | Token                | Score      |
|------------|----------------------|------------|
| 1986       | This                 | 36.7475    |
| 2124       | Of                   | 32.6924    |
| 28715      | Based                | 30.5650    |
| 785        | The                  | 29.3922    |
| 8420       | Here                 | 26.2325    |
| 95456      | Certainly            | 25.8768    |
| 32313      | Okay                 | 24.6308    |
| 2082       | An                   | 24.5454    |
| 1096       | This                 | 24.4082    |
| 43288      | 这                    | 24.0251    |

INFO:absl:
--- Similarity Metrics of Top Tokens ---
INFO:absl:| Metric                         | Value                |
|--------------------------------|----------------------|
| overlap_count                  | 10/10                |
| jaccard_similarity             | 1.0                  |
| rank_agreement_percentage      | 100.0                |

INFO:absl:
[probability: token 1]
INFO:absl:golden_probabilities[1]=Array([2.2498674e-09, 1.4269050e-11, 8.2976987e-07, ..., 1.1374250e-12,
       1.1374250e-12, 1.1374250e-12], dtype=float32)
INFO:absl:model_probabilities[1]=Array([2.2730862e-09, 1.4259688e-11, 8.3804821e-07, ..., 1.1365343e-12,
       1.1365343e-12, 1.1365343e-12], dtype=float32)
INFO:absl:
[KL divergence]
max KL divergence = 8.29e-04 at index 346, the corresponding token id is 419
INFO:absl:Checking KL Divergence between train distribution and golden distribution against threshold 0.1.

@hengtaoguo hengtaoguo 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.

Thanks for the quick fix!

--output-path=${GOLDEN_LOGITS_PATH} \
--prompts="${TEST_PROMPT}" \
--image-paths=${TEST_IMAGE} \
--hf-model-path=${LOCAL_PATH} \

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.

Great, I would recommend you to directly compare against HF model at this line instead of using LOCAL_PATH from the HF roundtrip conversion model.

As for the to_huggingface command, let's move it towards the end of this file. WDYT?

@subawocit subawocit force-pushed the update-logit-checker branch from e2d5f81 to c9f6111 Compare July 8, 2026 17:20

@shuningjin shuningjin 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.

Thank you for the tool enhancement, along with comprehensive doc and testing! Overall looks good. Some minor comments.

Comment thread tests/utils/forward_pass_logit_checker.py Outdated
Comment thread tests/end_to_end/tpu/qwen3/vl_2b/test_qwen3_vl_2b_to_hf_e2e.sh Outdated
image_path=${TEST_IMAGE} \
--max_kl_div=0.1 \
--golden_logits_path=${GOLDEN_LOGITS_PATH} \
override_model_config=true

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.

nit: Do we need override_model_config=true here (same for below)? I didn't see you change config in commands.

@subawocit subawocit Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Depends on how model's YAML config is initialized. In qwen3-vl models, we set use_multimodal: true in the config, and if we define USE_MULTIMODAL=false in .sh test file directly, we'll get this error:

ValueError: Keys ['use_multimodal'] are overridden by both model config and CLI/kwargs with different values.This is not allowed, unless setting override_model_config=True.

I added override_model_config=true to handle this.

Comment thread tests/utils/forward_pass_logit_checker.py
Comment thread tests/utils/forward_pass_logit_checker.py Outdated
Comment thread tests/utils/forward_pass_logit_checker.py Outdated
@subawocit subawocit force-pushed the update-logit-checker branch 2 times, most recently from 314e5e8 to 8d550d2 Compare July 9, 2026 22:49

@shuningjin shuningjin 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.

Great work! (let's squash commit before merge)

@subawocit subawocit force-pushed the update-logit-checker branch from ef2af73 to 144fb46 Compare July 9, 2026 23:55
add Qwen3 VL tests, update logit checker, and golden logit generator

Fix pyink formatting

Fix trailing whitespace and pyink list formatting

Fix final pyink indentation and comma

Fix pyink indentation

improve example usage; fix code

minor usage example change

minor update to test file; improve log output format

update to test file and description

pyink

update
@subawocit subawocit force-pushed the update-logit-checker branch from 8d84a47 to d81f8fa Compare July 9, 2026 23:59
@copybara-service copybara-service Bot merged commit 9885671 into main Jul 10, 2026
54 of 56 checks passed
@copybara-service copybara-service Bot deleted the update-logit-checker branch July 10, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants