.eval_results/mmmu_pro.yaml DELETED
@@ -1,8 +0,0 @@
1
- - dataset:
2
- id: MMMU/MMMU_Pro
3
- task_id: mmmu_pro_vision
4
- value: 76.9
5
- date: '2026-05-12'
6
- source:
7
- url: https://huggingface.co/google/gemma-4-31B-it
8
- name: Model Card
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -3,8 +3,6 @@ library_name: transformers
3
  license: apache-2.0
4
  license_link: https://ai.google.dev/gemma/docs/gemma_4_license
5
  pipeline_tag: image-text-to-text
6
- base_model:
7
- - google/gemma-4-31B
8
  ---
9
 
10
  <div align="center">
@@ -16,21 +14,20 @@ base_model:
16
  <a href="https://huggingface.co/collections/google/gemma-4" target="_blank">Hugging Face</a> |
17
  <a href="https://github.com/google-gemma" target="_blank">GitHub</a> |
18
  <a href="https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/" target="_blank">Launch Blog</a> |
19
- <a href="https://ai.google.dev/gemma/docs/core" target="_blank">Documentation</a>|
20
- <a href="https://arxiv.org/abs/2607.02770" target="_blank">Technical Report</a>
21
  <br>
22
  <b>License</b>: <a href="https://ai.google.dev/gemma/docs/gemma_4_license" target="_blank">Apache 2.0</a> | <b>Authors</b>: <a href="https://deepmind.google/models/gemma/" target="_blank">Google DeepMind</a>
23
  </p>
24
 
25
- Gemma is a family of open models built by Google DeepMind. Gemma 4 models are multimodal, handling text and image input (with audio supported on E2B, E4B, and 12B) and generating text output. This release includes open-weights models in both pre-trained and instruction-tuned variants. Gemma 4 features a context window of up to 256K tokens and maintains multilingual support in over 140 languages.
26
 
27
- Featuring both Dense and Mixture-of-Experts (MoE) architectures, Gemma 4 is well-suited for tasks like text generation, coding, and reasoning. The models are available in five distinct sizes: **E2B**, **E4B**, **12B**, **26B A4B**, and **31B**. Their diverse sizes make them deployable in environments ranging from high-end phones to laptops and servers, democratizing access to state-of-the-art AI.
28
 
29
  Gemma 4 introduces key **capability and architectural advancements**:
30
 
31
  * **Reasoning** – All models in the family are designed as highly capable reasoners, with configurable thinking modes.
32
 
33
- * **Extended Multimodalities** – Processes Text, Image with variable aspect ratio and resolution support (all models), Video, and Audio (featured natively on the E2B, E4B, and 12B models).
34
 
35
  * **Diverse & Efficient Architectures** – Offers Dense and Mixture-of-Experts (MoE) variants of different sizes for scalable deployment.
36
 
@@ -44,27 +41,25 @@ Gemma 4 introduces key **capability and architectural advancements**:
44
 
45
  ## **Models Overview**
46
 
47
- Gemma 4 models are designed to deliver frontier-level performance at each size, targeting deployment scenarios from mobile and edge devices (E2B, E4B) to consumer GPUs and workstations (12B, 26B A4B, 31B). They are well-suited for reasoning, agentic workflows, coding, and multimodal understanding.
48
 
49
  The models employ a hybrid attention mechanism that interleaves local sliding window attention with full global attention, ensuring the final layer is always global. This hybrid design delivers the processing speed and low memory footprint of a lightweight model without sacrificing the deep awareness required for complex, long-context tasks. To optimize memory for long contexts, global layers feature unified Keys and Values, and apply Proportional RoPE (p-RoPE).
50
 
51
  ### Dense Models
52
 
53
- | Property | E2B | E4B | 12B Unified | 31B Dense |
54
- | :---- | :---- | :---- | :---- | :---- |
55
- | **Total Parameters** | 2.3B effective <br> (5.1B with embeddings) | 4.5B effective <br> (8B with embeddings) | 11.95B | 30.7B |
56
- | **Layers** | 35 | 42 | 48 | 60 |
57
- | **Sliding Window** | 512 tokens | 512 tokens | 1024 tokens | 1024 tokens |
58
- | **Context Length** | 128K tokens | 128K tokens | 256K tokens | 256K tokens |
59
- | **Vocabulary Size** | 262K | 262K | 262K | 262K |
60
- | **Supported Modalities** | Text, Image, Audio | Text, Image, Audio | Text, Image, Audio | Text, Image |
61
- | **Vision Encoder Parameters** | *~150M* | *~150M* | - | *~550M* |
62
- | **Audio Encoder Parameters** | *~300M* | *~300M* | - | No Audio |
63
 
64
  The "E" in E2B and E4B stands for "effective" parameters. The smaller models incorporate Per-Layer Embeddings (PLE) to maximize parameter efficiency in on-device deployments. Rather than adding more layers or parameters to the model, PLE gives each decoder layer its own small embedding for every token. These embedding tables are large but are only used for quick lookups, which is why the effective parameter count is much smaller than the total.
65
 
66
- The "Unified" in Gemma 4 12B Unified refers to its encoder-free architecture. Other Gemma 4 models use dedicated encoders to process multimodal data before passing it to the LLM. Gemma 4 12B eliminates these encoders entirely, projecting raw image patches and audio waveforms directly into the LLM's embedding space through lightweight linear layers. This unified approach means all modalities flow straight into a single decoder-only transformer, reducing multimodal latency and allowing the entire model to be fine-tuned in one pass.
67
-
68
  ### Mixture-of-Experts (MoE) Model
69
 
70
  | Property | 26B A4B MoE |
@@ -85,44 +80,42 @@ The "A" in 26B A4B stands for "active parameters" in contrast to the total numbe
85
 
86
  These models were evaluated against a large collection of different datasets and metrics to cover different aspects of text generation. Evaluation results marked in the table are for instruction-tuned models.
87
 
88
- | | Gemma 4 31B | Gemma 4 26B A4B | Gemma 4 12B Unified | Gemma 4 E4B | Gemma 4 E2B | Gemma 3 27B (no think) |
89
- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |
90
- | MMLU Pro | 85.2% | 82.6% | 77.2% | 69.4% | 60.0% | 67.6% |
91
- | AIME 2026 no tools | 89.2% | 88.3% | 77.5% | 42.5% | 37.5% | 20.8% |
92
- | LiveCodeBench v6 | 80.0% | 77.1% | 72.0% | 52.0% | 44.0% | 29.1% |
93
- | Codeforces ELO | 2150 | 1718 | 1659 | 940 | 633 | 110 |
94
- | GPQA Diamond | 84.3% | 82.3% | 78.8% | 58.6% | 43.4% | 42.4% |
95
- | Tau2 (average over 3) | 76.9% | 68.2% | 69.0% | 42.2% | 24.5% | 16.2% |
96
- | HLE no tools | 19.5% | 8.7% | 5.2% | - | - | - |
97
- | HLE with search | 26.5% | 17.2% | - | - | - | - |
98
- | BigBench Extra Hard | 74.4% | 64.8% | 53.0% | 33.1% | 21.9% | 19.3% |
99
- | MMMLU | 88.4% | 86.3% | 83.4% | 76.6% | 67.4% | 70.7% |
100
- | **Vision** | | | | | | |
101
- | MMMU Pro | 76.9% | 73.8% | 69.1% | 52.6% | 44.2% | 49.7% |
102
- | OmniDocBench 1.5 (average edit distance, lower is better) | 0.131 | 0.149 | 0.164 | 0.181 | 0.290 | 0.365 |
103
- | MATH-Vision | 85.6% | 82.4% | 79.7% | 59.5% | 52.4% | 46.0% |
104
- | MedXPertQA MM | 61.3% | 58.1% | 48.7% | 28.7% | 23.5% | - |
105
- | **Audio** | | | | | | |
106
- | CoVoST | - | - | 38.5<sup>*</sup> | 35.54 | 33.47 | - |
107
- | FLEURS (lower is better) | - | - | 0.069<sup>*</sup> | 0.08 | 0.09 | - |
108
- | **Long Context** | | | | | | |
109
- | MRCR v2 8 needle 128k (average) | 66.4% | 44.1% | 43.4% | 25.4% | 19.1% | 13.5% |
110
-
111
- <sup>*</sup>Excluding Chinese language.
112
 
113
  ## **Core Capabilities**
114
 
115
  Gemma 4 models handle a broad range of tasks across text, vision, and audio. Key capabilities include:
116
 
117
  * **Thinking** – Built-in reasoning mode that lets the model think step-by-step before answering.
118
- * **Long Context** – Context windows of up to 128K tokens (E2B/E4B) and 256K tokens (12B, 26B A4B/31B).
119
  * **Image Understanding** – Object detection, Document/PDF parsing, screen and UI understanding, chart comprehension, OCR (including multilingual), handwriting recognition, and pointing. Images can be processed at variable aspect ratios and resolutions.
120
  * **Video Understanding** – Analyze video by processing sequences of frames.
121
  * **Interleaved Multimodal Input** – Freely mix text and images in any order within a single prompt.
122
  * **Function Calling** – Native support for structured tool use, enabling agentic workflows.
123
  * **Coding** – Code generation, completion, and correction.
124
  * **Multilingual** – Out-of-the-box support for 35+ languages, pre-trained on 140+ languages.
125
- * **Audio** (E2B, E4B, and 12B only) – Automatic speech recognition (ASR) and speech-to-translated-text translation across multiple languages.
126
 
127
  ## Getting Started
128
 
@@ -133,13 +126,13 @@ You can use all Gemma 4 models with the latest version of Transformers. To get s
133
  Once you have everything installed, you can proceed to load the model with the code below:
134
 
135
  ```python
136
- from transformers import AutoProcessor, AutoModelForMultimodalLM
137
 
138
  MODEL_ID = "google/gemma-4-31B-it"
139
 
140
  # Load model
141
  processor = AutoProcessor.from_pretrained(MODEL_ID)
142
- model = AutoModelForMultimodalLM.from_pretrained(
143
  MODEL_ID,
144
  dtype="auto",
145
  device_map="auto"
@@ -156,14 +149,13 @@ messages = [
156
  ]
157
 
158
  # Process input
159
- inputs = processor.apply_chat_template(
160
- messages,
161
- tokenize=True,
162
- return_dict=True,
163
- return_tensors="pt",
164
- add_generation_prompt=True,
165
  enable_thinking=False
166
- ).to(model.device)
 
167
  input_len = inputs["input_ids"].shape[-1]
168
 
169
  # Generate output
@@ -171,19 +163,20 @@ outputs = model.generate(**inputs, max_new_tokens=1024)
171
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
172
 
173
  # Parse output
174
- processor.parse_response(response, prefix=inputs["input_ids"])
175
  ```
176
 
177
  To enable reasoning, set `enable_thinking=True` and the `parse_response` function will take care of parsing the thinking output.
178
 
179
- Below, you will also find snippets for processing audio (E2B, E4B, 12B only), images, and video alongside text:
180
 
181
  <details>
182
  <summary>Code for processing Audio</summary>
183
 
184
- Make sure to install the following packages:
 
185
 
186
- `pip install -U transformers torch torchvision librosa accelerate`
187
 
188
  You can then load the model with the code below:
189
 
@@ -205,13 +198,13 @@ Once the model is loaded, you can start generating output by directly referencin
205
 
206
 
207
  ```python
208
- # Prompt - add audio after text
209
  messages = [
210
  {
211
  "role": "user",
212
  "content": [
 
213
  {"type": "text", "text": "Transcribe the following speech segment in its original language. Follow these specific instructions for formatting the answer:\n* Only output the transcription, with no newlines.\n* When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three."},
214
- {"type": "audio", "audio": "https://raw.githubusercontent.com/google-gemma/cookbook/refs/heads/main/apps/sample-data/journal1.wav"},
215
  ]
216
  }
217
  ]
@@ -231,7 +224,7 @@ outputs = model.generate(**inputs, max_new_tokens=512)
231
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
232
 
233
  # Parse output
234
- processor.parse_response(response, prefix=inputs["input_ids"])
235
  ```
236
 
237
  </details>
@@ -239,7 +232,7 @@ processor.parse_response(response, prefix=inputs["input_ids"])
239
  <details>
240
  <summary>Code for processing Images</summary>
241
 
242
- Make sure to install the following packages:
243
 
244
 
245
  `pip install -U transformers torch torchvision accelerate`
@@ -268,7 +261,7 @@ Once the model is loaded, you can start generating output by directly referencin
268
  messages = [
269
  {
270
  "role": "user", "content": [
271
- {"type": "image", "url": "https://raw.githubusercontent.com/google-gemma/cookbook/refs/heads/main/apps/sample-data/GoldenGate.png"},
272
  {"type": "text", "text": "What is shown in this image?"}
273
  ]
274
  }
@@ -289,7 +282,7 @@ outputs = model.generate(**inputs, max_new_tokens=512)
289
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
290
 
291
  # Parse output
292
- processor.parse_response(response, prefix=inputs["input_ids"])
293
  ```
294
 
295
  </details>
@@ -298,9 +291,9 @@ processor.parse_response(response, prefix=inputs["input_ids"])
298
  <details>
299
  <summary>Code for processing Videos</summary>
300
 
301
- Make sure to install the following packages:
302
 
303
- `pip install -U transformers torch torchvision librosa accelerate`
304
 
305
  You can then load the model with the code below:
306
 
@@ -348,13 +341,12 @@ outputs = model.generate(**inputs, max_new_tokens=512)
348
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
349
 
350
  # Parse output
351
- processor.parse_response(response, prefix=inputs["input_ids"])
352
  ```
353
 
354
  </details>
355
 
356
 
357
-
358
  ## **Best Practices**
359
 
360
  For the best performance, use these configurations and best practices:
@@ -382,14 +374,11 @@ Compared to Gemma 3, the models use standard `system`, `assistant`, and `user` r
382
 
383
  ### 3. Multi-Turn Conversations
384
 
385
- * **No Thinking Content in History**: In multi-turn conversations, the historical model output should only include the final response. Thoughts from previous model turns must *not be added* before the next user turn begins, with the exception of tool call turns where thinking content should be preserved.
386
 
387
  ### 4. Modality order
388
 
389
- For optimal performance with multimodal inputs, place:
390
-
391
- * Image content **before** the text in your prompt.
392
- * Audio content **after** the text in your prompt.
393
 
394
  ### 5. Variable Image Resolution
395
 
@@ -422,7 +411,7 @@ When formatting the answer, first output the transcription in {SOURCE_LANGUAGE},
422
 
423
  ### 7. Audio and Video Length
424
 
425
- All models support image inputs and can process videos as frames whereas the E2B, E4B, and 12B models also support audio inputs. Audio supports a maximum length of 30 seconds. Video supports a maximum of 60 seconds assuming the images are processed at one frame per second.
426
 
427
  ## **Model Data**
428
 
@@ -478,7 +467,7 @@ Multimodal models (capable of processing vision, language, and/or audio) have a
478
  * **Chatbots and Conversational AI**: Power conversational interfaces for customer service, virtual assistants, or interactive applications.
479
  * **Text Summarization**: Generate concise summaries of a text corpus, research papers, or reports.
480
  * **Image Data Extraction**: These models can be used to extract, interpret, and summarize visual data for text communications.
481
- * **Audio Processing and Interaction**: The E2B, E4B, and 12B models can analyze and interpret audio inputs, enabling voice-driven interactions and transcriptions.
482
  * **Research and Education**
483
  * **Natural Language Processing (NLP) and VLM Research**: These models can serve as a foundation for researchers to experiment with VLM and NLP techniques, develop algorithms, and contribute to the advancement of the field.
484
  * **Language Learning Tools**: Support interactive language learning experiences, aiding in grammar correction or providing writing practice.
@@ -522,20 +511,3 @@ The development of vision-language models (VLMs) raises several ethical concerns
522
  ### **Benefits**
523
 
524
  At the time of release, this family of models provides high-performance open vision-language model implementations designed from the ground up for responsible AI development compared to similarly sized models.
525
-
526
-
527
- ## **Citation**
528
-
529
- If you find our work helpful, please consider citing it:
530
-
531
- ```bibtex
532
- @misc{gemmateam2026gemma4,
533
- title={Gemma 4 Technical Report},
534
- author={Gemma Team},
535
- year={2026},
536
- eprint={2607.02770},
537
- archivePrefix={arXiv},
538
- primaryClass={cs.CL},
539
- url={https://arxiv.org/abs/2607.02770},
540
- }
541
- ```
 
3
  license: apache-2.0
4
  license_link: https://ai.google.dev/gemma/docs/gemma_4_license
5
  pipeline_tag: image-text-to-text
 
 
6
  ---
7
 
8
  <div align="center">
 
14
  <a href="https://huggingface.co/collections/google/gemma-4" target="_blank">Hugging Face</a> |
15
  <a href="https://github.com/google-gemma" target="_blank">GitHub</a> |
16
  <a href="https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/" target="_blank">Launch Blog</a> |
17
+ <a href="https://ai.google.dev/gemma/docs/core" target="_blank">Documentation</a>
 
18
  <br>
19
  <b>License</b>: <a href="https://ai.google.dev/gemma/docs/gemma_4_license" target="_blank">Apache 2.0</a> | <b>Authors</b>: <a href="https://deepmind.google/models/gemma/" target="_blank">Google DeepMind</a>
20
  </p>
21
 
22
+ Gemma is a family of open models built by Google DeepMind. Gemma 4 models are multimodal, handling text and image input (with audio supported on small models) and generating text output. This release includes open-weights models in both pre-trained and instruction-tuned variants. Gemma 4 features a context window of up to 256K tokens and maintains multilingual support in over 140 languages.
23
 
24
+ Featuring both Dense and Mixture-of-Experts (MoE) architectures, Gemma 4 is well-suited for tasks like text generation, coding, and reasoning. The models are available in four distinct sizes: **E2B**, **E4B**, **26B A4B**, and **31B**. Their diverse sizes make them deployable in environments ranging from high-end phones to laptops and servers, democratizing access to state-of-the-art AI.
25
 
26
  Gemma 4 introduces key **capability and architectural advancements**:
27
 
28
  * **Reasoning** – All models in the family are designed as highly capable reasoners, with configurable thinking modes.
29
 
30
+ * **Extended Multimodalities** – Processes Text, Image with variable aspect ratio and resolution support (all models), Video, and Audio (featured natively on the E2B and E4B models).
31
 
32
  * **Diverse & Efficient Architectures** – Offers Dense and Mixture-of-Experts (MoE) variants of different sizes for scalable deployment.
33
 
 
41
 
42
  ## **Models Overview**
43
 
44
+ Gemma 4 models are designed to deliver frontier-level performance at each size, targeting deployment scenarios from mobile and edge devices (E2B, E4B) to consumer GPUs and workstations (26B A4B, 31B). They are well-suited for reasoning, agentic workflows, coding, and multimodal understanding.
45
 
46
  The models employ a hybrid attention mechanism that interleaves local sliding window attention with full global attention, ensuring the final layer is always global. This hybrid design delivers the processing speed and low memory footprint of a lightweight model without sacrificing the deep awareness required for complex, long-context tasks. To optimize memory for long contexts, global layers feature unified Keys and Values, and apply Proportional RoPE (p-RoPE).
47
 
48
  ### Dense Models
49
 
50
+ | Property | E2B | E4B | 31B Dense |
51
+ | :---- | :---- | :---- | :---- |
52
+ | **Total Parameters** | 2.3B effective (5.1B with embeddings) | 4.5B effective (8B with embeddings) | 30.7B |
53
+ | **Layers** | 35 | 42 | 60 |
54
+ | **Sliding Window** | 512 tokens | 512 tokens | 1024 tokens |
55
+ | **Context Length** | 128K tokens | 128K tokens | 256K tokens |
56
+ | **Vocabulary Size** | 262K | 262K | 262K |
57
+ | **Supported Modalities** | Text, Image, Audio | Text, Image, Audio | Text, Image |
58
+ | **Vision Encoder Parameters** | *~150M* | *~150M* | *~550M* |
59
+ | **Audio Encoder Parameters** | *~300M* | *~300M* | No Audio |
60
 
61
  The "E" in E2B and E4B stands for "effective" parameters. The smaller models incorporate Per-Layer Embeddings (PLE) to maximize parameter efficiency in on-device deployments. Rather than adding more layers or parameters to the model, PLE gives each decoder layer its own small embedding for every token. These embedding tables are large but are only used for quick lookups, which is why the effective parameter count is much smaller than the total.
62
 
 
 
63
  ### Mixture-of-Experts (MoE) Model
64
 
65
  | Property | 26B A4B MoE |
 
80
 
81
  These models were evaluated against a large collection of different datasets and metrics to cover different aspects of text generation. Evaluation results marked in the table are for instruction-tuned models.
82
 
83
+ | | Gemma 4 31B | Gemma 4 26B A4B | Gemma 4 E4B | Gemma 4 E2B | Gemma 3 27B (no think) |
84
+ | :---- | :---- | :---- | :---- | :---- | :---- |
85
+ | MMLU Pro | 85.2% | 82.6% | 69.4% | 60.0% | 67.6% |
86
+ | AIME 2026 no tools | 89.2% | 88.3% | 42.5% | 37.5% | 20.8% |
87
+ | LiveCodeBench v6 | 80.0% | 77.1% | 52.0% | 44.0% | 29.1% |
88
+ | Codeforces ELO | 2150 | 1718 | 940 | 633 | 110 |
89
+ | GPQA Diamond | 84.3% | 82.3% | 58.6% | 43.4% | 42.4% |
90
+ | Tau2 (average over 3) | 76.9% | 68.2% | 42.2% | 24.5% | 16.2% |
91
+ | HLE no tools | 19.5% | 8.7% | - | - | - |
92
+ | HLE with search | 26.5% | 17.2% | - | - | - |
93
+ | BigBench Extra Hard | 74.4% | 64.8% | 33.1% | 21.9% | 19.3% |
94
+ | MMMLU | 88.4% | 86.3% | 76.6% | 67.4% | 70.7% |
95
+ | **Vision** | | | | | |
96
+ | MMMU Pro | 76.9% | 73.8% | 52.6% | 44.2% | 49.7% |
97
+ | OmniDocBench 1.5 (average edit distance, lower is better) | 0.131 | 0.149 | 0.181 | 0.290 | 0.365 |
98
+ | MATH-Vision | 85.6% | 82.4% | 59.5% | 52.4% | 46.0% |
99
+ | MedXPertQA MM | 61.3% | 58.1% | 28.7% | 23.5% | - |
100
+ | **Audio** | | | | | |
101
+ | CoVoST | - | - | 35.54 | 33.47 | - |
102
+ | FLEURS (lower is better) | - | - | 0.08 | 0.09 | - |
103
+ | **Long Context** | | | | | |
104
+ | MRCR v2 8 needle 128k (average) | 66.4% | 44.1% | 25.4% | 19.1% | 13.5% |
 
 
105
 
106
  ## **Core Capabilities**
107
 
108
  Gemma 4 models handle a broad range of tasks across text, vision, and audio. Key capabilities include:
109
 
110
  * **Thinking** – Built-in reasoning mode that lets the model think step-by-step before answering.
111
+ * **Long Context** – Context windows of up to 128K tokens (E2B/E4B) and 256K tokens (26B A4B/31B).
112
  * **Image Understanding** – Object detection, Document/PDF parsing, screen and UI understanding, chart comprehension, OCR (including multilingual), handwriting recognition, and pointing. Images can be processed at variable aspect ratios and resolutions.
113
  * **Video Understanding** – Analyze video by processing sequences of frames.
114
  * **Interleaved Multimodal Input** – Freely mix text and images in any order within a single prompt.
115
  * **Function Calling** – Native support for structured tool use, enabling agentic workflows.
116
  * **Coding** – Code generation, completion, and correction.
117
  * **Multilingual** – Out-of-the-box support for 35+ languages, pre-trained on 140+ languages.
118
+ * **Audio** (E2B and E4B only) – Automatic speech recognition (ASR) and speech-to-translated-text translation across multiple languages.
119
 
120
  ## Getting Started
121
 
 
126
  Once you have everything installed, you can proceed to load the model with the code below:
127
 
128
  ```python
129
+ from transformers import AutoProcessor, AutoModelForCausalLM
130
 
131
  MODEL_ID = "google/gemma-4-31B-it"
132
 
133
  # Load model
134
  processor = AutoProcessor.from_pretrained(MODEL_ID)
135
+ model = AutoModelForCausalLM.from_pretrained(
136
  MODEL_ID,
137
  dtype="auto",
138
  device_map="auto"
 
149
  ]
150
 
151
  # Process input
152
+ text = processor.apply_chat_template(
153
+ messages,
154
+ tokenize=False,
155
+ add_generation_prompt=True,
 
 
156
  enable_thinking=False
157
+ )
158
+ inputs = processor(text=text, return_tensors="pt").to(model.device)
159
  input_len = inputs["input_ids"].shape[-1]
160
 
161
  # Generate output
 
163
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
164
 
165
  # Parse output
166
+ processor.parse_response(response)
167
  ```
168
 
169
  To enable reasoning, set `enable_thinking=True` and the `parse_response` function will take care of parsing the thinking output.
170
 
171
+ Below, you will also find snippets for processing audio (E2B and E4B only), images, and video alongside text:
172
 
173
  <details>
174
  <summary>Code for processing Audio</summary>
175
 
176
+ Instead of using `AutoModelForCausalLM`, you can use `AutoModelForMultimodalLM` to process audio. To use it, make sure to install the following packages:
177
+
178
 
179
+ `pip install -U transformers torch librosa accelerate`
180
 
181
  You can then load the model with the code below:
182
 
 
198
 
199
 
200
  ```python
201
+ # Prompt - add audio before text
202
  messages = [
203
  {
204
  "role": "user",
205
  "content": [
206
+ {"type": "audio", "audio": "https://raw.githubusercontent.com/google-gemma/cookbook/refs/heads/main/Demos/sample-data/journal1.wav"},
207
  {"type": "text", "text": "Transcribe the following speech segment in its original language. Follow these specific instructions for formatting the answer:\n* Only output the transcription, with no newlines.\n* When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three."},
 
208
  ]
209
  }
210
  ]
 
224
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
225
 
226
  # Parse output
227
+ processor.parse_response(response)
228
  ```
229
 
230
  </details>
 
232
  <details>
233
  <summary>Code for processing Images</summary>
234
 
235
+ Instead of using `AutoModelForCausalLM`, you can use `AutoModelForMultimodalLM` to process images. To use it, make sure to install the following packages:
236
 
237
 
238
  `pip install -U transformers torch torchvision accelerate`
 
261
  messages = [
262
  {
263
  "role": "user", "content": [
264
+ {"type": "image", "url": "https://raw.githubusercontent.com/google-gemma/cookbook/refs/heads/main/Demos/sample-data/GoldenGate.png"},
265
  {"type": "text", "text": "What is shown in this image?"}
266
  ]
267
  }
 
282
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
283
 
284
  # Parse output
285
+ processor.parse_response(response)
286
  ```
287
 
288
  </details>
 
291
  <details>
292
  <summary>Code for processing Videos</summary>
293
 
294
+ Instead of using `AutoModelForCausalLM`, you can use `AutoModelForMultimodalLM` to process videos. To use it, make sure to install the following packages:
295
 
296
+ `pip install -U transformers torch torchvision torchcodec librosa accelerate`
297
 
298
  You can then load the model with the code below:
299
 
 
341
  response = processor.decode(outputs[0][input_len:], skip_special_tokens=False)
342
 
343
  # Parse output
344
+ processor.parse_response(response)
345
  ```
346
 
347
  </details>
348
 
349
 
 
350
  ## **Best Practices**
351
 
352
  For the best performance, use these configurations and best practices:
 
374
 
375
  ### 3. Multi-Turn Conversations
376
 
377
+ * **No Thinking Content in History**: In multi-turn conversations, the historical model output should only include the final response. Thoughts from previous model turns must *not be added* before the next user turn begins.
378
 
379
  ### 4. Modality order
380
 
381
+ * For optimal performance with multimodal inputs, place image and/or audio content **before** the text in your prompt.
 
 
 
382
 
383
  ### 5. Variable Image Resolution
384
 
 
411
 
412
  ### 7. Audio and Video Length
413
 
414
+ All models support image inputs and can process videos as frames whereas the E2B and E4B models also support audio inputs. Audio supports a maximum length of 30 seconds. Video supports a maximum of 60 seconds assuming the images are processed at one frame per second.
415
 
416
  ## **Model Data**
417
 
 
467
  * **Chatbots and Conversational AI**: Power conversational interfaces for customer service, virtual assistants, or interactive applications.
468
  * **Text Summarization**: Generate concise summaries of a text corpus, research papers, or reports.
469
  * **Image Data Extraction**: These models can be used to extract, interpret, and summarize visual data for text communications.
470
+ * **Audio Processing and Interaction**: The smaller models (E2B and E4B) can analyze and interpret audio inputs, enabling voice-driven interactions and transcriptions.
471
  * **Research and Education**
472
  * **Natural Language Processing (NLP) and VLM Research**: These models can serve as a foundation for researchers to experiment with VLM and NLP techniques, develop algorithms, and contribute to the advancement of the field.
473
  * **Language Learning Tools**: Support interactive language learning experiences, aiding in grammar correction or providing writing practice.
 
511
  ### **Benefits**
512
 
513
  At the time of release, this family of models provides high-performance open vision-language model implementations designed from the ground up for responsible AI development compared to similarly sized models.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chat_template.jinja CHANGED
@@ -1,15 +1,9 @@
1
- {#
2
- Template: Google Gemma 4 Canonical Chat Template
3
- Author: Google Gemma Engineering Team
4
- Published: 2026-07-09
5
- Context: Fixed tool-calling loops, turn closures, and thinking content-ordering.
6
- #}
7
- {%- macro format_parameters(properties, required, filter_keys=false) -%}
8
  {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}
9
  {%- set ns = namespace(found_first=false) -%}
10
  {%- for key, value in properties | dictsort -%}
11
  {%- set add_comma = false -%}
12
- {%- if not filter_keys or key not in standard_keys -%}
13
  {%- if ns.found_first %},{% endif -%}
14
  {%- set ns.found_first = true -%}
15
  {{ key }}:{
@@ -17,15 +11,34 @@
17
  description:<|"|>{{ value['description'] }}<|"|>
18
  {%- set add_comma = true -%}
19
  {%- endif -%}
 
 
 
 
20
  {%- if value['type'] | upper == 'STRING' -%}
21
  {%- if value['enum'] -%}
22
  {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
23
  enum:{{ format_argument(value['enum']) }}
24
  {%- endif -%}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  {%- elif value['type'] | upper == 'ARRAY' -%}
26
  {%- if value['items'] is mapping and value['items'] -%}
27
- {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
28
- items:{
29
  {%- set ns_items = namespace(found_first=false) -%}
30
  {%- for item_key, item_value in value['items'] | dictsort -%}
31
  {%- if item_value is not none -%}
@@ -58,32 +71,6 @@
58
  }
59
  {%- endif -%}
60
  {%- endif -%}
61
- {%- if value['nullable'] %}
62
- {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
63
- nullable:true
64
- {%- endif -%}
65
- {%- if value['type'] | upper == 'OBJECT' -%}
66
- {%- if value['properties'] is defined and value['properties'] is mapping -%}
67
- {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
68
- properties:{
69
- {{- format_parameters(value['properties'], value['required'] | default([])) -}}
70
- }
71
- {%- elif value is mapping -%}
72
- {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
73
- properties:{
74
- {{- format_parameters(value, value['required'] | default([]), filter_keys=true) -}}
75
- }
76
- {%- endif -%}
77
- {%- if value['required'] -%}
78
- {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
79
- required:[
80
- {%- for item in value['required'] | default([]) -%}
81
- <|"|>{{- item -}}<|"|>
82
- {%- if not loop.last %},{% endif -%}
83
- {%- endfor -%}
84
- ]
85
- {%- endif -%}
86
- {%- endif -%}
87
  {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
88
  type:<|"|>{{ value['type'] | upper }}<|"|>}
89
  {%- endif -%}
@@ -122,9 +109,7 @@
122
  }
123
  {%- endmacro -%}
124
  {%- macro format_argument(argument, escape_keys=True) -%}
125
- {%- if argument is none -%}
126
- {{- 'null' -}}
127
- {%- elif argument is string -%}
128
  {{- '<|"|>' + argument + '<|"|>' -}}
129
  {%- elif argument is boolean -%}
130
  {{- 'true' if argument else 'false' -}}
@@ -165,45 +150,24 @@
165
  {{- ns.result | trim -}}
166
  {%- endmacro -%}
167
 
168
- {%- macro format_tool_response_block(tool_name, response) -%}
169
- {{- '<|tool_response>' -}}
170
- {%- if response is mapping -%}
171
- {{- 'response:' + tool_name + '{' -}}
172
- {%- for key, value in response | dictsort -%}
173
- {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
174
- {%- if not loop.last %},{% endif -%}
175
- {%- endfor -%}
176
- {{- '}' -}}
177
- {%- else -%}
178
- {{- 'response:' + tool_name + '{value:' + format_argument(response, escape_keys=False) + '}' -}}
179
- {%- endif -%}
180
- {{- '<tool_response|>' -}}
181
- {%- endmacro -%}
182
-
183
- {#- ===== SETUP ===== -#}
184
- {%- set ns = namespace(prev_message_type=None, prev_non_tool_role=None) -%}
185
  {%- set loop_messages = messages -%}
186
- {%- set enable_thinking = enable_thinking | default(false) -%}
187
- {%- set preserve_thinking = preserve_thinking | default(false) -%}
188
- {{- bos_token -}}
189
  {#- Handle System/Tool Definitions Block -#}
190
- {%- if enable_thinking or tools or (messages and messages[0]['role'] in ['system', 'developer']) -%}
191
  {{- '<|turn>system\n' -}}
 
192
  {#- Inject Thinking token at the very top of the FIRST system turn -#}
193
- {%- if enable_thinking -%}
194
- {{- '<|think|>\n' -}}
195
  {%- set ns.prev_message_type = 'think' -%}
196
  {%- endif -%}
197
- {%- if messages and messages[0]['role'] in ['system', 'developer'] -%}
198
- {%- if messages[0]['content'] is string -%}
199
- {{- messages[0]['content'] | trim -}}
200
- {%- elif messages[0]['content'] is sequence -%}
201
- {%- for item in messages[0]['content'] -%}
202
- {{- item['text'] | trim + ' '-}}
203
- {%- endfor -%}
204
- {%- endif -%}
205
  {%- set loop_messages = messages[1:] -%}
206
  {%- endif -%}
 
207
  {%- if tools -%}
208
  {%- for tool in tools %}
209
  {{- '<|tool>' -}}
@@ -212,38 +176,18 @@
212
  {%- endfor %}
213
  {%- set ns.prev_message_type = 'tool' -%}
214
  {%- endif -%}
 
215
  {{- '<turn|>\n' -}}
216
  {%- endif %}
217
 
218
- {#- Pre-scan: find last user message index for reasoning guard -#}
219
- {%- set ns_turn = namespace(last_user_idx=-1) -%}
220
- {%- for i in range(loop_messages | length) -%}
221
- {%- if loop_messages[i]['role'] == 'user' -%}
222
- {%- set ns_turn.last_user_idx = i -%}
223
- {%- endif -%}
224
- {%- endfor -%}
225
-
226
  {#- Loop through messages -#}
227
  {%- for message in loop_messages -%}
228
- {%- if message['role'] != 'tool' -%}
229
  {%- set ns.prev_message_type = None -%}
230
  {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
231
- {#- Detect continuation using tracked state — O(1) instead of O(n) backward scan -#}
232
- {%- set continue_same_model_turn = (role == 'model' and ns.prev_non_tool_role == 'assistant') -%}
233
- {%- if not continue_same_model_turn -%}
234
  {{- '<|turn>' + role + '\n' }}
235
 
236
- {%- endif -%}
237
-
238
- {#- Render reasoning/reasoning_content as thinking channel -#}
239
- {%- set thinking_text = message.get('reasoning') or message.get('reasoning_content') -%}
240
- {%- set thinking_gate = (loop.index0 > ns_turn.last_user_idx) or (preserve_thinking and message.get('tool_calls')) -%}
241
- {%- if thinking_text and thinking_gate -%}
242
- {{- '<|channel>thought\n' + thinking_text + '\n<channel|>' -}}
243
- {%- endif -%}
244
-
245
- {%- if message.get('tool_calls') -%}
246
- {%- for tool_call in message.get('tool_calls') -%}
247
  {%- set function = tool_call['function'] -%}
248
  {{- '<|tool_call>call:' + function['name'] + '{' -}}
249
  {%- if function['arguments'] is mapping -%}
@@ -253,138 +197,70 @@
253
  {%- set ns_args.found_first = true -%}
254
  {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
255
  {%- endfor -%}
256
- {%- elif function['arguments'] is none -%}
257
- {%- else -%}
258
- {{- raise_exception(
259
- "chat_template: tool_calls[].function.arguments must be a "
260
- "JSON object (mapping), not a string. Deserialize arguments "
261
- "before passing to the template."
262
- ) -}}
263
  {%- endif -%}
264
  {{- '}<tool_call|>' -}}
265
  {%- endfor -%}
266
  {%- set ns.prev_message_type = 'tool_call' -%}
267
  {%- endif -%}
268
 
269
- {%- set ns_tr_out = namespace(flag=false) -%}
270
- {%- if message.get('tool_responses') -%}
271
- {#- Legacy: tool_responses embedded on the assistant message (Google/Gemma native) -#}
272
- {%- for tool_response in message.get('tool_responses') -%}
273
- {{- format_tool_response_block(tool_response['name'] | default('unknown', true), tool_response['response']) -}}
274
- {%- set ns_tr_out.flag = true -%}
275
- {%- set ns.prev_message_type = 'tool_response' -%}
276
- {%- endfor -%}
277
- {%- elif message.get('tool_calls') -%}
278
- {#- OpenAI Chat Completions: forward-scan consecutive role:tool messages -#}
279
- {%- set ns_tool_scan = namespace(stopped=false) -%}
280
- {%- for k in range(loop.index0 + 1, loop_messages | length) -%}
281
- {%- if ns_tool_scan.stopped -%}
282
- {%- elif loop_messages[k]['role'] != 'tool' -%}
283
- {%- set ns_tool_scan.stopped = true -%}
284
- {%- else -%}
285
- {%- set follow = loop_messages[k] -%}
286
- {#- Resolve tool_call_id to function name -#}
287
- {%- set ns_tname = namespace(name=follow.get('name') or 'unknown') -%}
288
- {%- for tc in message.get('tool_calls') -%}
289
- {%- if tc.get('id') == follow.get('tool_call_id') -%}
290
- {%- set ns_tname.name = tc['function']['name'] -%}
291
- {%- endif -%}
292
  {%- endfor -%}
293
- {#- Handle content as string or content-parts array -#}
294
- {%- set tool_body = follow.get('content') -%}
295
- {%- if tool_body is string -%}
296
- {{- format_tool_response_block(ns_tname.name, tool_body) -}}
297
- {%- elif tool_body is sequence and tool_body is not string -%}
298
- {%- set ns_txt = namespace(s='') -%}
299
- {%- for part in tool_body -%}
300
- {%- if part.get('type') == 'text' -%}
301
- {%- set ns_txt.s = ns_txt.s + (part.get('text') | default('')) -%}
302
- {%- endif -%}
303
- {%- endfor -%}
304
- {{- format_tool_response_block(ns_tname.name, ns_txt.s) -}}
305
- {%- for part in tool_body -%}
306
- {%- if part.get('type') in ['image', 'image_url'] -%}
307
- {{- '<|image|>' -}}
308
- {%- elif part.get('type') in ['audio', 'input_audio'] -%}
309
- {{- '<|audio|>' -}}
310
- {%- elif part.get('type') == 'video' -%}
311
- {{- '<|video|>' -}}
312
- {%- endif -%}
313
- {%- endfor -%}
314
- {%- else -%}
315
- {{- format_tool_response_block(ns_tname.name, tool_body) -}}
316
- {%- endif -%}
317
- {%- set ns_tr_out.flag = true -%}
318
- {%- set ns.prev_message_type = 'tool_response' -%}
319
  {%- endif -%}
 
320
  {%- endfor -%}
 
321
  {%- endif -%}
322
 
323
- {%- set captured_content -%}
324
- {%- if message.get('content') is string -%}
325
  {%- if role == 'model' -%}
326
  {{- strip_thinking(message['content']) -}}
327
  {%- else -%}
328
  {{- message['content'] | trim -}}
329
  {%- endif -%}
330
- {%- elif message.get('content') is sequence -%}
331
  {%- for item in message['content'] -%}
332
- {%- if item.get('type') == 'text' -%}
333
  {%- if role == 'model' -%}
334
  {{- strip_thinking(item['text']) -}}
335
  {%- else -%}
336
  {{- item['text'] | trim -}}
337
  {%- endif -%}
338
- {%- elif item.get('type') in ['image', 'image_url'] -%}
339
- {{- '<|image|>' -}}
340
- {%- elif item.get('type') in ['audio', 'input_audio'] -%}
 
341
  {{- '<|audio|>' -}}
342
- {%- elif item.get('type') == 'video' -%}
343
- {{- '<|video|>' -}}
 
 
344
  {%- endif -%}
345
  {%- endfor -%}
346
  {%- endif -%}
347
- {%- endset -%}
348
-
349
- {{- captured_content -}}
350
- {%- set has_content = captured_content | trim | length > 0 -%}
351
 
352
- {#- Forward-scan: find next non-tool message role for continuation detection -#}
353
- {%- set next_nt = namespace(role=None, found=false) -%}
354
- {%- for j in range(loop.index0 + 1, loop_messages | length) -%}
355
- {%- if not next_nt.found -%}
356
- {%- if loop_messages[j]['role'] != 'tool' -%}
357
- {%- set next_nt.role = loop_messages[j]['role'] -%}
358
- {%- set next_nt.found = true -%}
359
- {%- endif -%}
360
- {%- endif -%}
361
- {%- endfor -%}
362
-
363
- {%- set continues_into_next = (
364
- role == 'model'
365
- and next_nt.role == 'assistant'
366
- and (not message.get('tool_calls') or ns_tr_out.flag)
367
- ) -%}
368
-
369
- {%- if ns.prev_message_type == 'tool_call' and not ns_tr_out.flag -%}
370
- {{- '<|tool_response>' -}}
371
- {%- elif continues_into_next -%}
372
- {%- elif not (ns_tr_out.flag and not has_content and not next_nt.found) -%}
373
  {{- '<turn|>\n' -}}
374
  {%- endif -%}
375
-
376
- {#- Track previous non-tool role for next iteration (avoids O(n) backward scan) -#}
377
- {%- set ns.prev_non_tool_role = message['role'] -%}
378
- {%- endif -%}
379
  {%- endfor -%}
380
 
381
  {%- if add_generation_prompt -%}
382
- {%- if ns.prev_message_type != 'tool_response' and ns.prev_message_type != 'tool_call' -%}
383
  {{- '<|turn>model\n' -}}
384
- {%- if not enable_thinking -%}
385
- {{- '<|channel>thought\n<channel|>' -}}
386
- {%- endif -%}
387
- {%- elif ns.prev_message_type == 'tool_response' and enable_thinking -%}
388
- {{- '<|channel>thought\n' -}}
389
  {%- endif -%}
390
  {%- endif -%}
 
1
+ {%- macro format_parameters(properties, required) -%}
 
 
 
 
 
 
2
  {%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}
3
  {%- set ns = namespace(found_first=false) -%}
4
  {%- for key, value in properties | dictsort -%}
5
  {%- set add_comma = false -%}
6
+ {%- if key not in standard_keys -%}
7
  {%- if ns.found_first %},{% endif -%}
8
  {%- set ns.found_first = true -%}
9
  {{ key }}:{
 
11
  description:<|"|>{{ value['description'] }}<|"|>
12
  {%- set add_comma = true -%}
13
  {%- endif -%}
14
+ {%- if value['nullable'] %}
15
+ {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
16
+ nullable:true
17
+ {%- endif -%}
18
  {%- if value['type'] | upper == 'STRING' -%}
19
  {%- if value['enum'] -%}
20
  {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
21
  enum:{{ format_argument(value['enum']) }}
22
  {%- endif -%}
23
+ {%- elif value['type'] | upper == 'OBJECT' -%}
24
+ ,properties:{
25
+ {%- if value['properties'] is defined and value['properties'] is mapping -%}
26
+ {{- format_parameters(value['properties'], value['required'] | default([])) -}}
27
+ {%- elif value is mapping -%}
28
+ {{- format_parameters(value, value['required'] | default([])) -}}
29
+ {%- endif -%}
30
+ }
31
+ {%- if value['required'] -%}
32
+ ,required:[
33
+ {%- for item in value['required'] | default([]) -%}
34
+ <|"|>{{- item -}}<|"|>
35
+ {%- if not loop.last %},{% endif -%}
36
+ {%- endfor -%}
37
+ ]
38
+ {%- endif -%}
39
  {%- elif value['type'] | upper == 'ARRAY' -%}
40
  {%- if value['items'] is mapping and value['items'] -%}
41
+ ,items:{
 
42
  {%- set ns_items = namespace(found_first=false) -%}
43
  {%- for item_key, item_value in value['items'] | dictsort -%}
44
  {%- if item_value is not none -%}
 
71
  }
72
  {%- endif -%}
73
  {%- endif -%}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  {%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
75
  type:<|"|>{{ value['type'] | upper }}<|"|>}
76
  {%- endif -%}
 
109
  }
110
  {%- endmacro -%}
111
  {%- macro format_argument(argument, escape_keys=True) -%}
112
+ {%- if argument is string -%}
 
 
113
  {{- '<|"|>' + argument + '<|"|>' -}}
114
  {%- elif argument is boolean -%}
115
  {{- 'true' if argument else 'false' -}}
 
150
  {{- ns.result | trim -}}
151
  {%- endmacro -%}
152
 
153
+ {%- set ns = namespace(prev_message_type=None) -%}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  {%- set loop_messages = messages -%}
155
+ {{ bos_token }}
 
 
156
  {#- Handle System/Tool Definitions Block -#}
157
+ {%- if (enable_thinking is defined and enable_thinking) or tools or messages[0]['role'] in ['system', 'developer'] -%}
158
  {{- '<|turn>system\n' -}}
159
+
160
  {#- Inject Thinking token at the very top of the FIRST system turn -#}
161
+ {%- if enable_thinking is defined and enable_thinking -%}
162
+ {{- '<|think|>' -}}
163
  {%- set ns.prev_message_type = 'think' -%}
164
  {%- endif -%}
165
+
166
+ {%- if messages[0]['role'] in ['system', 'developer'] -%}
167
+ {{- messages[0]['content'] | trim -}}
 
 
 
 
 
168
  {%- set loop_messages = messages[1:] -%}
169
  {%- endif -%}
170
+
171
  {%- if tools -%}
172
  {%- for tool in tools %}
173
  {{- '<|tool>' -}}
 
176
  {%- endfor %}
177
  {%- set ns.prev_message_type = 'tool' -%}
178
  {%- endif -%}
179
+
180
  {{- '<turn|>\n' -}}
181
  {%- endif %}
182
 
 
 
 
 
 
 
 
 
183
  {#- Loop through messages -#}
184
  {%- for message in loop_messages -%}
 
185
  {%- set ns.prev_message_type = None -%}
186
  {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
 
 
 
187
  {{- '<|turn>' + role + '\n' }}
188
 
189
+ {%- if message['tool_calls'] -%}
190
+ {%- for tool_call in message['tool_calls'] -%}
 
 
 
 
 
 
 
 
 
191
  {%- set function = tool_call['function'] -%}
192
  {{- '<|tool_call>call:' + function['name'] + '{' -}}
193
  {%- if function['arguments'] is mapping -%}
 
197
  {%- set ns_args.found_first = true -%}
198
  {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
199
  {%- endfor -%}
200
+ {%- elif function['arguments'] is string -%}
201
+ {{- function['arguments'] -}}
 
 
 
 
 
202
  {%- endif -%}
203
  {{- '}<tool_call|>' -}}
204
  {%- endfor -%}
205
  {%- set ns.prev_message_type = 'tool_call' -%}
206
  {%- endif -%}
207
 
208
+ {%- if message['tool_responses'] -%}
209
+ {#- Tool Response handling -#}
210
+ {%- for tool_response in message['tool_responses'] -%}
211
+ {{- '<|tool_response>' -}}
212
+ {%- if tool_response['response'] is mapping -%}
213
+ {{- 'response:' + tool_response['name'] | default('unknown') + '{' -}}
214
+ {%- for key, value in tool_response['response'] | dictsort -%}
215
+ {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
216
+ {%- if not loop.last %},{% endif -%}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  {%- endfor -%}
218
+ {{- '}' -}}
219
+ {%- else -%}
220
+ {{- 'response:' + tool_response['name'] | default('unknown') + '{value:' + format_argument(tool_response['response'], escape_keys=False) + '}' -}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  {%- endif -%}
222
+ {{- '<tool_response|>' -}}
223
  {%- endfor -%}
224
+ {%- set ns.prev_message_type = 'tool_response' -%}
225
  {%- endif -%}
226
 
227
+ {%- if message['content'] is string -%}
 
228
  {%- if role == 'model' -%}
229
  {{- strip_thinking(message['content']) -}}
230
  {%- else -%}
231
  {{- message['content'] | trim -}}
232
  {%- endif -%}
233
+ {%- elif message['content'] is sequence -%}
234
  {%- for item in message['content'] -%}
235
+ {%- if item['type'] == 'text' -%}
236
  {%- if role == 'model' -%}
237
  {{- strip_thinking(item['text']) -}}
238
  {%- else -%}
239
  {{- item['text'] | trim -}}
240
  {%- endif -%}
241
+ {%- elif item['type'] == 'image' -%}
242
+ {{- '\n\n<|image|>\n\n' -}}
243
+ {%- set ns.prev_message_type = 'image' -%}
244
+ {%- elif item['type'] == 'audio' -%}
245
  {{- '<|audio|>' -}}
246
+ {%- set ns.prev_message_type = 'audio' -%}
247
+ {%- elif item['type'] == 'video' -%}
248
+ {{- '\n\n<|video|>\n\n' -}}
249
+ {%- set ns.prev_message_type = 'video' -%}
250
  {%- endif -%}
251
  {%- endfor -%}
252
  {%- endif -%}
 
 
 
 
253
 
254
+ {%- if not (message['tool_responses'] and not message['content']) -%}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  {{- '<turn|>\n' -}}
256
  {%- endif -%}
 
 
 
 
257
  {%- endfor -%}
258
 
259
  {%- if add_generation_prompt -%}
260
+ {%- if ns.prev_message_type != 'tool_response' -%}
261
  {{- '<|turn>model\n' -}}
262
+ {%- endif -%}
263
+ {%- if not enable_thinking | default(false) -%}
264
+ {{- '<|channel>thought\n<channel|>' -}}
 
 
265
  {%- endif -%}
266
  {%- endif -%}
tokenizer_config.json CHANGED
@@ -61,53 +61,7 @@
61
  }
62
  }
63
  },
64
- "x-regex": "(\\<\\|channel\\>thought\\n(?P<thinking>.*?)\\<channel\\|\\>)?(?P<tool_calls>\\<\\|tool_call\\>.*\\<tool_call\\|\\>)?(?P<content>(?:(?!\\<turn\\|\\>)(?!\\<\\|tool_response\\>).)+)?(?:\\<turn\\|\\>|\\<\\|tool_response\\>)?"
65
- },
66
- "response_template": {
67
- "defaults": {
68
- "role": "assistant"
69
- },
70
- "fields": {
71
- "content": {
72
- "close": [
73
- "<turn|>",
74
- "<|tool_response>",
75
- "<eos>"
76
- ],
77
- "content": "text"
78
- },
79
- "thinking": {
80
- "close": "<channel|>",
81
- "content": "text",
82
- "open": "<|channel>thought\n"
83
- },
84
- "tool_calls": {
85
- "close": "<tool_call|>",
86
- "content": "json",
87
- "content_args": {
88
- "string_delims": [
89
- [
90
- "<|\"|>",
91
- "<|\"|>"
92
- ]
93
- ],
94
- "unquoted_keys": true
95
- },
96
- "open_pattern": "<\\|tool_call>call:(?P<name>\\w+)",
97
- "repeats": true,
98
- "transform": {
99
- "function": {
100
- "arguments": "{content}",
101
- "name": "{name}"
102
- },
103
- "type": "function"
104
- }
105
- }
106
- },
107
- "start_anchor": [
108
- "<|turn>model\n",
109
- "<tool_response|>"
110
- ]
111
  },
112
  "soc_token": "<|channel>",
113
  "sot_token": "<|turn>",
 
61
  }
62
  }
63
  },
64
+ "x-regex": "(\\<\\|channel\\>thought\\n(?P<thinking>.*?)\\<channel\\|\\>)?(?P<content>(?:(?!\\<\\|tool_call\\>)(?!\\<turn\\|\\>).)+)?(?P<tool_calls>\\<\\|tool_call\\>.*\\<tool_call\\|\\>)?(?:\\<turn\\|\\>)?"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  },
66
  "soc_token": "<|channel>",
67
  "sot_token": "<|turn>",