Skip to content

Commit 53dea32

Browse files
Merge pull request #4148 from AI-Hypercomputer:hengtaoguo-doc
PiperOrigin-RevId: 932745123
2 parents e0b220a + b93eda4 commit 53dea32

6 files changed

Lines changed: 217 additions & 4 deletions

File tree

docs/tutorials/posttraining/multimodal.md

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ This document provides a guide to use the multimodal functionalities in MaxText
88

99
We also provide a [colab](https://github.com/AI-Hypercomputer/maxtext/blob/main/src/maxtext/examples/multimodal_gemma3_demo.ipynb) for multimodal features demonstration. The following table provides a list of models and modalities we currently support:
1010

11-
| Models | Input Modalities | Output Modalities |
12-
| :--------------------------------------------- | :--------------- | :---------------- |
13-
| - Gemma3-4B/12B/27B<br>- Llama4-Scout/Maverick | Text, images | Text |
11+
| Models | Input: Text | Input: Image | Input: Video | Input: Audio | Output |
12+
| :-------------------------- | :---------: | :----------: | :----------: | :----------: | :----: |
13+
| **Gemma3** (4B/12B/27B) ||| | | Text |
14+
| **Gemma4** (26B/31B) ||| | | Text |
15+
| **Llama4** (Scout/Maverick) ||| | | Text |
16+
| **Qwen3-Omni** ||||| Text |
17+
| **Qwen3.5** (35B/397B) |||| | Text |
1418

1519
## Introduction
1620

@@ -73,6 +77,8 @@ MaxText supports multimodal decoding, allowing you to input text with multiple i
7377

7478
Since each model uses a unique native chatting template from its pretraining, we've implemented these specific templates within `multimodal_utils.py` and apply them directly to your prompt.
7579

80+
### Decode with text+image
81+
7682
To run a forward pass and verify the model's output, use the following command:
7783

7884
```shell
@@ -124,10 +130,47 @@ python -m maxtext.inference.decode \
124130

125131
For larger models such as Llama4-Scout/Maverick, we suggest to run the decoding on a TPU cluster such as v5p-16.
126132

133+
### Decode with text+video+audio
134+
135+
For models that support video input (e.g., Qwen3-Omni and Qwen3.5), pass a video file via `video_path`. For Qwen3-Omni, which also supports audio, set `use_audio_in_video=true` to additionally process the embedded audio track. Since the required token budget scales with video length and resolution, set `max_prefill_predict_length` accordingly.
136+
137+
```shell
138+
# Qwen3-Omni decode with video + audio
139+
export MAXTEXT_CKPT_PATH=<Checkpoint GCS path> # gs://my-bucket/path for Qwen3-Omni
140+
python -m maxtext.inference.decode \
141+
model_name=qwen3-omni-30b-a3b \
142+
tokenizer_path=Qwen/Qwen3-Omni-30B-A3B-Instruct \
143+
tokenizer_type=huggingface \
144+
load_parameters_path=${MAXTEXT_CKPT_PATH?}/0/items \
145+
per_device_batch_size=1 \
146+
run_name=ht_test \
147+
steps=1 \
148+
async_checkpointing=false \
149+
scan_layers=false \
150+
use_multimodal=true \
151+
use_audio_in_video=true \
152+
prompt='What can you see and hear? Answer in one short sentence.' \
153+
video_path='tests/assets/test_video.mp4' \
154+
max_prefill_predict_length=1250 \
155+
max_target_length=1280 \
156+
add_bos=false \
157+
attention='dot_product' \
158+
```
159+
160+
The expected output will look similar to:
161+
162+
```
163+
Input `<|im_start|>user
164+
<|vision_start|><|video_pad|><|vision_end|>What can you see and hear? Answer in one short sentence.<|im_end|>
165+
<|im_start|>assistant
166+
` -> `A roaring Tyrannosaurus rex animatronic is displayed in a museum exhibit.
167+
```
168+
127169
## Supervised Fine-Tuning
128170

129171
Supervised Fine-Tuning (SFT) of multimodal LLMs in MaxText focuses specifically on post-training; we don't yet support pre-training multimodal models from scratch. The SFT process typically involves training on Visual Question Answering (VQA) datasets where the model learns to generate accurate text responses based on both visual and textual inputs. During this fine-tuning phase, we recommend to freeze the pre-trained encoder layers (such as vision transformers) to preserve their learned visual representations, while the projection layers and LLM decoder components remain trainable. This selective training strategy allows the model to adapt the cross-modal alignment and text generation capabilities without disrupting the robust feature extraction abilities of the encoders, ultimately leading to improved performance on multimodal understanding and reasoning tasks while maintaining computational efficiency. This is achieved by setting `freeze_vision_encoder_params=True` in [sft-vision-chartqa.yml](https://github.com/AI-Hypercomputer/maxtext/blob/main/src/maxtext/configs/post_train/sft-vision-chartqa.yml).
130-
Here, we use [ChartQA](https://huggingface.co/datasets/HuggingFaceM4/ChartQA) as an example to demonstrate SFT functionality:
172+
173+
**Text+image SFT is supported for all models listed above.** The following example uses Gemma3-4B with the [ChartQA](https://huggingface.co/datasets/HuggingFaceM4/ChartQA) dataset:
131174

132175
```shell
133176
export MAXTEXT_CKPT_PATH=<your-checkpoints-path> # either set to an already available MaxText ckpt or to the one we just converted in the previous step

tests/end_to_end/tpu/gemma3/Run_Gemma3.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
We provide examples for checkpoint conversion and decoding/training/finetuning Gemma3 in test scripts at [tests/end_to_end/tpu/gemma3](https://github.com/AI-Hypercomputer/maxtext/tree/main/tests/end_to_end/tpu/gemma3).
2222

23+
For multimodal functionality, see the [Multimodal Support guide](../../../../docs/tutorials/posttraining/multimodal.md).
24+
2325

2426
## Pre-training
2527
You can train from scratch to generate a new checkpoint. One example command to run pretraining Gemma3-4B model is as follows:

tests/end_to_end/tpu/llama4/Run_Llama4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* LLama4 Maverick (17B-128E)
2323
* Llama4 Maverick (17B-128E-Instruct)
2424

25+
For multimodal functionality, see the [Multimodal Support guide](../../../../docs/tutorials/posttraining/multimodal.md).
2526

2627
## Checkpoint conversion
2728
Currently, we support converting both [PyTorch](https://www.llama.com/) and [HuggingFace](https://huggingface.co/collections/meta-llama/llama-4-67f0c30d9fe03840bc9d0164) checkpoints. Note that we recommend using the `huggingface-cli download` command with environment variable
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
3+
# This file is documentation for how to get started with Qwen3-Omni-30B-A3B.
4+
5+
# This file runs Step 1 on CPU.
6+
# 1. Convert the HuggingFace checkpoint (bf16) to MaxText-compatible checkpoint (bf16):
7+
# Unscanned format is used here as it is better suited for decoding.
8+
# ---
9+
# Example Usage:
10+
#
11+
# export HF_TOKEN=<your_hf_token>
12+
# export BASE_OUTPUT_PATH=gs://your-gcs-bucket/qwen3-omni-30b-a3b_maxtext_ckpt
13+
# bash tests/end_to_end/tpu/qwen/moe/qwen3-omni-30b-a3b/1_test_qwen3_omni_30b_a3b.sh
14+
# ---
15+
16+
set -ex
17+
18+
export MODEL_NAME="${MODEL_NAME:-qwen3-omni-30b-a3b}"
19+
export TOKENIZER_PATH="${TOKENIZER_PATH:-Qwen/Qwen3-Omni-30B-A3B-Instruct}"
20+
21+
# (Optional) Path to your local Hugging Face checkpoint
22+
export HF_MODEL_PATH="${HF_MODEL_PATH:-}"
23+
24+
# Base output path for MaxText checkpoint.
25+
export BASE_OUTPUT_PATH="${BASE_OUTPUT_PATH:-gs://your-gcs-bucket/qwen3-omni-30b-a3b_maxtext_ckpt}"
26+
27+
if [ -z "${HF_TOKEN}" ]; then
28+
echo "Error: HF_TOKEN environment variable is not set. Please export your Hugging Face token."
29+
echo "Example: export HF_TOKEN=hf_..."
30+
exit 1
31+
fi
32+
33+
# Strip trailing slash from base path to avoid malformed URIs
34+
BASE_OUTPUT_PATH=${BASE_OUTPUT_PATH%/}
35+
echo "Using BASE_OUTPUT_PATH = ${BASE_OUTPUT_PATH}"
36+
37+
# Install torch for checkpoint conversion
38+
python3 -m pip install torch --index-url https://download.pytorch.org/whl/cpu
39+
40+
# Setup local HF path argument if one was provided
41+
HF_LOCAL_ARG=""
42+
if [ -n "${HF_MODEL_PATH}" ]; then
43+
HF_LOCAL_ARG="hf_model_path=${HF_MODEL_PATH}"
44+
fi
45+
46+
# ---
47+
# Step 1: Checkpoint Conversion
48+
# Convert HuggingFace checkpoint to MaxText unscanned format (better for decoding).
49+
# use_multimodal=true is required to include vision/audio encoder weights.
50+
# ---
51+
JAX_PLATFORMS=cpu python3 -m maxtext.checkpoint_conversion.to_maxtext src/maxtext/configs/base.yml \
52+
model_name=${MODEL_NAME} \
53+
base_output_directory=${BASE_OUTPUT_PATH}/unscanned \
54+
hf_access_token=${HF_TOKEN} \
55+
scan_layers=false \
56+
use_multimodal=true \
57+
--lazy_load_tensors=False \
58+
${HF_LOCAL_ARG}
59+
60+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
3+
# This file is documentation for how to get started with Qwen3-Omni-30B-A3B.
4+
5+
# This file runs Step 2 on a v5p-8 TPU VM.
6+
# 2. Run multimodal decoding: text+image, and text+video+audio.
7+
# ---
8+
# Example Usage:
9+
#
10+
# export HF_TOKEN=<your_hf_token>
11+
# export BASE_OUTPUT_PATH=gs://your-gcs-bucket/qwen3-omni-30b-a3b_maxtext_ckpt
12+
# bash tests/end_to_end/tpu/qwen/moe/qwen3-omni-30b-a3b/2_test_qwen3_omni_30b_a3b.sh
13+
# ---
14+
15+
set -ex
16+
17+
export MODEL_NAME="${MODEL_NAME:-qwen3-omni-30b-a3b}"
18+
export TOKENIZER_PATH="${TOKENIZER_PATH:-Qwen/Qwen3-Omni-30B-A3B-Instruct}"
19+
20+
if [ -z "${BASE_OUTPUT_PATH}" ]; then
21+
# Non-Googlers please remember to point `BASE_OUTPUT_PATH` to GCS buckets that you own, this script uses internal buckets for testing.
22+
# this bucket will store all the files generated by MaxText during a run
23+
export BASE_OUTPUT_PATH=gs://runner-maxtext-logs/$(date +%Y-%m-%d-%H-%M)
24+
echo "BASE_OUTPUT_PATH is not set"
25+
fi
26+
BASE_OUTPUT_PATH=${BASE_OUTPUT_PATH%/}
27+
echo using BASE_OUTPUT_PATH = ${BASE_OUTPUT_PATH}
28+
29+
if [ -z "${HF_TOKEN}" ]; then
30+
echo "Error: HF_TOKEN environment variable is not set. Please export your Hugging Face token."
31+
echo "Example: export HF_TOKEN=hf_..."
32+
exit 1
33+
fi
34+
35+
UNSCANNED_CKPT_PATH=gs://maxtext-model-checkpoints/qwen3-omni-30b-a3b/unscanned/0/items
36+
37+
# ---
38+
# Step 2a: Multimodal Decode — text + image
39+
# Uses a test image from the repo assets.
40+
# max_prefill_predict_length accounts for image tokens (~256) + text prompt tokens.
41+
# ---
42+
python3 -m maxtext.inference.decode ${MAXTEXT_CONFIGS_DIR:-${MAXTEXT_REPO_ROOT:-$PWD}/src/maxtext/configs}/base.yml \
43+
model_name=${MODEL_NAME} \
44+
tokenizer_path=${TOKENIZER_PATH} \
45+
tokenizer_type=huggingface \
46+
load_parameters_path=${UNSCANNED_CKPT_PATH} \
47+
hf_access_token=${HF_TOKEN} \
48+
per_device_batch_size=1 \
49+
run_name=qwen3_omni_decode_image \
50+
steps=1 \
51+
async_checkpointing=false \
52+
scan_layers=false \
53+
use_multimodal=true \
54+
prompt='Describe this image in one sentence.' \
55+
image_path='tests/assets/test_image.jpg' \
56+
max_prefill_predict_length=512 \
57+
max_target_length=542 \
58+
add_bos=false \
59+
attention=dot_product
60+
61+
# ---
62+
# Step 2b: Multimodal Decode — text + video + audio
63+
# Passes a video file and enables audio processing from the video track.
64+
# max_prefill_predict_length is set higher to accommodate video frame tokens (~1126)
65+
# plus audio tokens (~77) plus text prompt tokens.
66+
# ---
67+
python3 -m maxtext.inference.decode ${MAXTEXT_CONFIGS_DIR:-${MAXTEXT_REPO_ROOT:-$PWD}/src/maxtext/configs}/base.yml \
68+
model_name=${MODEL_NAME} \
69+
tokenizer_path=${TOKENIZER_PATH} \
70+
tokenizer_type=huggingface \
71+
load_parameters_path=${UNSCANNED_CKPT_PATH} \
72+
hf_access_token=${HF_TOKEN} \
73+
per_device_batch_size=1 \
74+
run_name=qwen3_omni_decode_video \
75+
steps=1 \
76+
async_checkpointing=false \
77+
scan_layers=false \
78+
use_multimodal=true \
79+
use_audio_in_video=true \
80+
prompt='What can you see and hear? Answer in one short sentence.' \
81+
video_path='tests/assets/test_video.mp4' \
82+
max_prefill_predict_length=1240 \
83+
max_target_length=1280 \
84+
add_bos=false \
85+
attention=dot_product

tests/end_to_end/tpu/qwen/moe/run_qwen_moe.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ Qwen3 is a family of open-source large language models from the Qwen team at Ali
99

1010
- **Qwen3-480B-A35B**
1111

12+
- **Qwen3-Omni-30B-A3B**
13+
1214
- **Qwen3.5-397B-A17B**
1315

1416
- **Qwen3.5-35B-A3B**
1517

1618
For more details on Qwen3 architecture, see the [Qwen3 Technical Report](https://arxiv.org/abs/2505.09388).
1719

20+
For more details on Qwen3-Omni architecture, see the [Qwen3-Omni Technical Report](https://arxiv.org/abs/2509.17765).
21+
1822
For more details on Qwen3.5 architecture, see the [Qwen3.5 Blog](https://qwen.ai/blog?id=qwen3.5)
1923

24+
For multimodal functionality (image, video, and audio input), see the [Multimodal Support guide](../../../../../docs/tutorials/posttraining/multimodal.md).
25+
2026
* * * * *
2127

2228
Checkpoint Conversion
@@ -153,6 +159,22 @@ export MAXTEXT_CHECKPOINT_PATH=gs://your-gcs-bucket/qwen3-480b-a35b_maxtext_ckpt
153159
bash tests/end_to_end/tpu/qwen/moe/qwen3-480b-a35b/1_test_qwen3_480b_a35b.sh
154160
```
155161

162+
### Qwen3-Omni-30B-A3B
163+
164+
```bash
165+
# 1. Export your Hugging Face token
166+
export HF_TOKEN="your_hf_token_here"
167+
168+
# 2. Set the base path for conversion and SFT outputs
169+
export BASE_OUTPUT_PATH=gs://<YOUR-GCS-BUCKET>/qwen3-omni-30b-a3b_maxtext_ckpt
170+
171+
# (Optional) Set the path if you are using a local Hugging Face checkpoint instead of downloading
172+
# export HF_MODEL_PATH=/path/to/local/qwen3-omni-30b-a3b_hf_checkpoint
173+
174+
# 3. Execute the conversion and multimodal decode verification
175+
bash tests/end_to_end/tpu/qwen/moe/qwen3-omni-30b-a3b/1_test_qwen3_omni_30b_a3b.sh
176+
```
177+
156178
### Qwen3.5-35B-A3B
157179

158180
```bash

0 commit comments

Comments
 (0)