Instructions to use google/diffusiongemma-26B-A4B-it with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use google/diffusiongemma-26B-A4B-it with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="google/diffusiongemma-26B-A4B-it") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("google/diffusiongemma-26B-A4B-it") model = AutoModelForMultimodalLM.from_pretrained("google/diffusiongemma-26B-A4B-it", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use google/diffusiongemma-26B-A4B-it with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "google/diffusiongemma-26B-A4B-it" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "google/diffusiongemma-26B-A4B-it", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/google/diffusiongemma-26B-A4B-it
- SGLang
How to use google/diffusiongemma-26B-A4B-it with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "google/diffusiongemma-26B-A4B-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "google/diffusiongemma-26B-A4B-it", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "google/diffusiongemma-26B-A4B-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "google/diffusiongemma-26B-A4B-it", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use google/diffusiongemma-26B-A4B-it with Docker Model Runner:
docker model run hf.co/google/diffusiongemma-26B-A4B-it
Add {% generation %} markers so SFT frameworks can extract the assistant mask
Problem
chat_template.jinja has no {% generation %}...{% endgeneration %} markers, soapply_chat_template(..., return_assistant_tokens_mask=True) cannot return an assistant mask.
SFT frameworks then fall back to prefix-length heuristics to locate the supervised region, and
those heuristics place the boundary before the <|turn>model\n header rather than after it.
The model is therefore trained to re-emit the turn header as the first thing in its response.
Because model is an ordinary (non-special) token, it survives detokenization and shows up as a
stray model\n at the start of generations. (When the base channel prior wins instead, it
surfaces as thought\n.)
Concretely, with NVIDIA NeMo AutoModel's ChatDataset — the framework used by the official
DiffusionGemma SFT guide —
on one openai/gsm8k row (transformers 4.57.6):
| supervised-region start | inference prompt length | |
|---|---|---|
| current template | 43 | 46 |
| this PR | 46 | 46 |
The 3 wrongly-supervised tokens are <|turn> (105), model (4368), \n (107).
Filed upstream as NVIDIA-NeMo/Automodel#3352; the framework side should also assert this
boundary, but shipping generation markers here fixes it for every framework at once.
Fix
One semantic hunk. The assistant content and its turn close are captured into variables and
emitted together inside a single generation block:
- {{- captured_content -}}
{%- set has_content = captured_content | trim | length > 0 -%}
{#- Forward-scan ... -#} (unchanged)
+ {%- set captured_close -%}
{%- if ns.prev_message_type == 'tool_call' and not ns_tr_out.flag -%}
{{- '<|tool_response>' -}}
{%- elif continues_into_next -%}
{%- elif not (ns_tr_out.flag and not has_content and not next_nt.found) -%}
{{- '<turn|>\n' -}}
{%- endif -%}
+ {%- endset -%}
+
+ {%- if role == 'model' -%}
+ {% generation %}{{- captured_content -}}{{- captured_close -}}{% endgeneration %}
+ {%- else -%}
+ {{- captured_content -}}{{- captured_close -}}
+ {%- endif -%}
Two deliberate choices:
- The turn close stays inside the generation block, so termination remains supervised.
DeepMind's own SFT pipeline does the same — inhackable_diffusion_adapter
the prompt template ends with<|turn>model\nand the response template is"{text}<turn|>",
i.e. the header belongs to the prompt and the closer belongs to the supervised response. This
PR makes the chat template agree with that boundary. - The forward-scan block is hoisted above the content emission so both can sit in one
generation block. It only assigns variables (next_nt,ns_tr_out) and depends solely onloop_messages, so the rendered text is unchanged.
Verification
- rendered text is byte-identical to the current template (all render modes)
- supervised-region start now equals the inference prompt length exactly
- inference prompt length unchanged
-
{% generation %}detected by the standard regex, soreturn_assistant_tokens_mask=True
returnsassistant_masksinstead of falling back
Notes
- Orthogonal to #25. That PR moves the
{%- endif -%}aroundns.prev_non_tool_role; this
one inserts a generation block just above it. The two are textually adjacent but semantically
independent and can be merged in either order. - The same gap exists in
google/gemma-4-31B-itandgoogle/gemma-4-E4B-it(also 0 generation
markers). I've limited this PR to DiffusionGemma since it's the variant with a documented SFT
recipe, but the same patch shape applies to the whole Gemma 4 template family if you'd prefer
to fix it consistently.