Downloads · 30 days
39
18% of all-time downloads
sriq-ai/sriq-diffusiongemma-26B-A4B-v1.6
sriq-diffusiongemma-26B-A4B-v1.6 is a image-text-to-text model from sriq-ai. Use it for the image-text-to-text task on the model card, and read the license before you ship it in a product. It is set up for transformers. The card lists the license as apache-2.0.
<div align="center" <img src="https://huggingface.co/sriq-ai/sriq-diffusiongemma-26B-A4B-v1.6/resolve/main/banner.png" width="100%" alt="SRIQ-DiffusionGemma-26B-A4B-V1.6 — compressed reasoning" / </div
Downloads · 30 days
39
18% of all-time downloads
All-time downloads
217
Public
Parameters
25.8B
52 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors51.9 GB · 100%
From the Hugging Face model README
Merged bf16 weights — a full model, not an adapter. A LoRA trained on sriq-ai/sriq-sft-v1.6 has been merged into kaivoss/diffusiongemma-26B-A4B-it-ALWAYS-THINK, so it loads and serves like any HF checkpoint with no PEFT in the path.
The model reasons in compressed Simplified Chinese and answers in the language it was asked in.
DiffusionGemma is not autoregressive: a causal encoder reads the prompt into a read-only KV cache, and a bidirectional decoder denoises a 256-token canvas over ~48 refinement passes.
20 held-out prompts (seeded random 5% split of v1.6's 9,988 rows), 384 new tokens, 48 denoising steps.
| base | this model | |
|---|---|---|
| mean CJK fraction of generation | 0.0% | 18.1% |
| rows producing any Chinese | 0 / 20 | 18 / 20 |
| per-row range | 0.0% | 0.0% – 58.6% |
Base scores zero on every row, so the shift is unambiguous.
Training step count matters a lot here — the same recipe at 200 steps reaches less than two thirds of the coverage:
| steps | mean CJK | rows with Chinese |
|---|---|---|
| 200 | 12.4% | 12 / 20 |
| 800 | 18.1% | 18 / 20 |
v1.6 supervises traces that catch a real mistake and repair it (19.5% of rows). That shows up in generation — the model abandons a bad line of attack rather than rationalising it:
配方:3(x-1/3)^2+3(y-1/3)^2=3+2/3=11/3。
不对。重新检查x+y=3z。
The v1.5 model did the opposite: it produced steps containing p | p-1 (true for no
prime) and stamped the result correct.
2 of 20 held-out rows collapse into a repeated phrase until the token budget runs out,
e.g. 验1≤x,y,z≤100。 emitted a dozen times. The base model does this on 0 of 20, so
finetuning introduced it.
Measured by zlib compression ratio (looped text compresses far harder than prose):
| base | this model | |
|---|---|---|
| mean zlib ratio | 0.461 | 0.481 |
| rows below 0.12 | 0 / 20 | 2 / 20 |
The mean is slightly higher than base, so output is not globally repetitive — 18 of 20 rows land between 0.35 and 0.61. It is a minority failure mode, not a general collapse, but it is real and you will hit it.
Reasoning validity is also not benchmarked. Only the language shift and this repetition rate were measured; no accuracy evaluation was run.
import torch
from transformers import AutoModelForImageTextToText, AutoTokenizer
M = "sriq-ai/sriq-diffusiongemma-26B-A4B-v1.6"
tok = AutoTokenizer.from_pretrained(M)
model = AutoModelForImageTextToText.from_pretrained(M, dtype=torch.bfloat16,
device_map={"": 0}).eval()
messages = [{"role": "user", "content": "求所有正整数 n,使得 n^2 | 2^n+1。"}]
ids = tok.apply_chat_template(messages, add_generation_prompt=True, tokenize=True,
return_dict=False)
inp = torch.tensor([ids], device="cuda")
gen = model.generation_config # ships max_denoising_steps = 48
gen.max_new_tokens = 1536
with torch.no_grad():
out = model.generate(input_ids=inp, generation_config=gen)
print(tok.decode(out.sequences[0, inp.shape[1]:], skip_special_tokens=True))
Needs ~52 GB VRAM in bf16 on one accelerator (A100 80GB / H100). The ~46 GB of MoE
experts are fused 3D parameters, so load_in_4bit does not shrink them.
An FP8 build is available at sriq-ai/sriq-diffusiongemma-26B-A4B-v1.6-FP8-dynamic — 27.2 GB instead of 51.6 GB, so it fits on one 40 GB card, with no measured quality loss (8.0% vs 5.9% mean CJK when both are served through the same vLLM build). It needs Hopper/Ada or newer. The commands below are for these bf16 weights.
Because these are merged weights, vLLM serves them directly — no LoRA support required. SGLang does not support this architecture yet (see below).
docker pull vllm/vllm-openai:gemma
docker run -itd --name sriq-diffusiongemma \
--ipc=host --network host --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:gemma \
--model sriq-ai/sriq-diffusiongemma-26B-A4B-v1.6 \
--max-model-len 262144 \
--max-num-seqs 4 \
--gpu-memory-utilization 0.85 \
--host 0.0.0.0 --port 8000
Requires vLLM 0.24.0+. Keep --max-num-seqs low: diffusion state buffers pre-allocate
max_seqs × canvas_length × vocab_size tensors, so it costs VRAM in a way ordinary
autoregressive serving does not.
SGLang cannot serve DiffusionGemma. --dllm-algorithm Gemma4Renoise parses, which
makes it look supported, but the flag value is not a registered algorithm and the
architecture is not a registered model:
RuntimeError: Unknown diffusion LLM: DiffusionGemmaForBlockDiffusion
Verified on lmsysorg/sglang:latest (v0.5.20). The dLLM registry in
srt/dllm/config.py holds only LLaDA2MoeModelLM, SDARForCausalLM and
SDARMoeForCausalLM — on the released image and on main — and srt/dllm/algorithm/
contains no renoise sampler. This is not specific to these weights: Google's own
checkpoint declares the same architectures.
Support is in PR #34061, still open, and it adds bf16 serving only. The LMSYS cookbook page documents the command ahead of the code. Use vLLM until that lands.
Full writeup in FINETUNE.md; scripts are train.py and
merge.py. The unmerged adapter is in adapter/.
Objective follows NVIDIA NeMo Automodel's recipe:
total = diffusion_CE + encoder_loss_weight * encoder_AR_CE
The AR term is not optional — the diffusion term alone teaches denoising and nothing about the text distribution, and produces no style transfer at all.
| rank / alpha | 32 / 64 (tied) |
| trainable params | 37,171,200 (0.14%) |
| target modules | attention + dense MLP, text backbone; MoE experts and router frozen |
| lr / schedule | 1.5e-4, OneCycle, betas (0.95, 0.99), wd 1e-4 |
| steps / grad accum | 800 / 4 |
| self-conditioning | two-pass, p=0.5 |
| max context | 6144 (keeps 96.1% of rows; over-long rows dropped, never truncated) |
| hardware | 4× A100 80GB, ~63 GiB peak, ~2h20m |
Encoder and decoder share tied base weights, which dictates the adapter's shape:
Δ_enc + Δ_dec.lora_A/lora_B, so both
compute W+Δ during training and the AR loss reaches it. merge.py then writes Δ
into the tied tensor once.peft's merge_and_unload() would walk both modules and write Δ twice into the same
storage. NVIDIA's own tools/merge_lora.py uses that path and has no tied-weight
handling, so it is not safe for this architecture either.