muse-glimmer-30b-kernelgen

Generates Triton GPU kernels from PyTorch module specifications. Merged fine-tune for developers porting nn.Module code to hand-written @triton.jit kernels.

This is a merged fine-tune of meta-models/Muse-Glimmer-30B: the LoRA adapter has been fused into the base weights with merge_and_unload(), so it loads as an ordinary transformers checkpoint with no PEFT dependency. It was trained with QLoRA (4-bit NF4 base) via TRL SFT.

Model details

Developed by SASVA AI Model Cognition Labs(MCL) Team
Base model meta-models/Muse-Glimmer-30B
Base parameters 29.8B (~1.8B of which is the vision tower, left untouched)
Architecture family muse_glimmer (MuseGlimmerForConditionalGeneration)
Adaptation LoRA (r=16, alpha=32, dropout=0.05), merged into the base
Trainable modules q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
Excluded modules .*vision_tower.* (the vision tower was not adapted)
Training method qlora (4-bit NF4 base, bf16 compute)
Refinement none (SFT only)
Precision in this repo bfloat16, unquantized
Weights 2 safetensors shards, 56 GB total
Context length 131,072 (base capability); trained at 8,192
Language English (source code + identifiers)
License Apache-2.0, inherited from the base model

The config here carries no quantization_config — 4-bit was a training-time choice, not a property of these weights.

Intended use

Direct use. Given a PyTorch nn.Module (plus the get_inputs() / get_init_inputs() helpers that define its shapes), emit a self-contained Python file implementing the same computation with @triton.jit kernels and host-side launch code.

The prompt format is part of the contract. The model was trained on one exact rendering; see How to get started. Prompting it as a general chat model will not reproduce its behaviour.

How to get started

Prompt format

The model uses the base model's ATEM chat template. Training rendered each sample as (newlines shown literally):

<|begin_of_text|><|start|>system<|message|>{SYSTEM}

Reasoning strength: high.

# Valid recipients: "self", "user".<|eot|><|start|>user<|message|>{INSTRUCTION}

```
{PYTORCH_SOURCE}
```<|eot|><|start|>assistant to=user<|message|>{TRITON_SOURCE}<|eot|>

Three things follow from this, and all three bite in practice:

  1. The Reasoning strength: high. and # Valid recipients: lines are injected by the template itself — they were part of every training sample. Use apply_chat_template; do not hand-build the string.
  2. The user turn is instruction, then a blank line, then the source inside a fenced code block.
  3. add_generation_prompt=True stops at <|start|>assistant, so the model itself emits the recipient header to=user before the code. This is correct behaviour, not a bug — strip everything up to and including the header, or prefill it.

System prompt

This is the exact system prompt the adapter was trained under, recovered from the training launch command. Changing it moves the model off its trained contract.

You are a GPU kernel engineer. Given a specification (either a PyTorch nn.Module to port or a custom_kernel signature with reference implementation), write a complete, correct, and fast Python source file using Triton @triton.jit kernels with appropriate host-side launcher code, preserving the exact public class name and forward signature or custom_kernel entry point as specified. Output only raw Python source code with no explanation or markdown.

Note the tension between that prompt and the data: it says "preserving the exact public class name", but the training targets follow the KernelBook convention of appending New (relu -> reluNew). The data wins — the model renames the class. Do not rely on the prompt's wording here.

Loading it

from_pretrained requests files by name, so it fetches the config, tokenizer and safetensors shards only — the GGUF in this repo costs transformers users nothing. If you instead download the repo by hand, filter it, or you will pull all 73 GB:

hf download SASVAAI/muse-glimmer-30b-kernelgen --exclude "*.gguf" --local-dir ./muse-glimmer-kernelgen

Requires a transformers build that knows model_type: muse_glimmer. It is not in any stable PyPI release as of 2026-09-14 — install from git main. Note also that AutoModelForCausalLM cannot load this architecture (muse_glimmer has no causal-LM mapping at all); use AutoModelForImageTextToText.

import torch
from transformers import AutoModelForImageTextToText, AutoTokenizer

MODEL = "SASVAAI/muse-glimmer-30b-kernelgen"

tokenizer = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True)
model = AutoModelForImageTextToText.from_pretrained(
    MODEL, dtype=torch.bfloat16, device_map="auto",
    trust_remote_code=True, attn_implementation="sdpa",
)
model.eval()

SYSTEM = (
    "You are a GPU kernel engineer. Given a specification (either a PyTorch "
    "nn.Module to port or a custom_kernel signature with reference "
    "implementation), write a complete, correct, and fast Python source file "
    "using Triton @triton.jit kernels with appropriate host-side launcher "
    "code, preserving the exact public class name and forward signature or "
    "custom_kernel entry point as specified. Output only raw Python source "
    "code with no explanation or markdown."
)

instruction = "Write a complete, self-contained Triton implementation that computes the same result."
pytorch_src = '''import torch

class RMulInt(torch.nn.Module):
    def forward(self, x):
        return 10 * x

def get_inputs():
    return [torch.rand([4, 4, 4, 4])]

def get_init_inputs():
    return [[], {}]
'''

messages = [
    {"role": "system", "content": SYSTEM},
    {"role": "user", "content": f"{instruction}\n\n```\n{pytorch_src.strip()}\n```"},
]
inputs = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, enable_thinking=False,
    tokenize=True, return_tensors="pt",
).to(model.device)

out = model.generate(inputs, max_new_tokens=2048, do_sample=False)
text = tokenizer.decode(out[0][inputs.shape[-1]:], skip_special_tokens=True)

# Strip the ATEM recipient header the model emits before its content.
print(text.split("to=user", 1)[-1].lstrip() if "to=user" in text else text)

Run locally with Ollama

The Q4_K_M GGUF ships in this repo, so there is nothing to build. Either of these works:

# A. One command — Ollama pulls the GGUF straight from this repo
ollama run hf.co/SASVAAI/muse-glimmer-30b-kernelgen

# B. Or fetch the GGUF plus the Modelfile and build the tag locally
hf download SASVAAI/muse-glimmer-30b-kernelgen \
    --include "*Q4_K_M.gguf" "Modelfile" --local-dir .
ollama create muse-glimmer-kernelgen -f Modelfile
ollama run muse-glimmer-kernelgen

Either way you download 16.9 GB, not the 56 GB of bf16 safetensors — Ollama only fetches the GGUF.

The two paths are not quite equivalent. ollama run hf.co/... never reads a Modelfile. The Hub serves this repo to Ollama through its own OCI-compatible registry: it picks the Q4_K_M GGUF as the model layer, and attaches this repo's params and system files as the parameter and system-prompt layers. Those two files are kept byte-equivalent to the Modelfile's PARAMETER lines and SYSTEM block, so both routes land on the same greedy, system-prompted configuration. The chat template comes from the GGUF's embedded tokenizer.chat_template on both paths (see below). Path B is the one to use if you want to edit any of it.

What the hf.co path serves

Path A depends on machinery outside this repo: the Hub renders a GGUF repo as an Ollama manifest, and Ollama pulls it like a container image. That was tested directly against the Hub's registry rather than assumed.

The transport works. ollama pull hf.co/bartowski/Llama-3.2-1B-Instruct-GGUF on this host (Ollama v0.34.0) fetched 807 MB at 156 MB/s, wrote a manifest with model / template / params layers exactly as the registry declared them, and /api/generate returned done_reason: "stop". Nothing about the mechanism is specific to that repo.

The Hub uses your files when you provide them. Fetching GET https://huggingface.co/v2/{repo}/manifests/latest for repos that ship a loose params or template file — Qwen/Qwen3-4B-GGUF, unsloth/gpt-oss-20b-GGUF — returns layers byte-identical to those files. Repos with no such files (bartowski/Llama-3.2-1B-Instruct-GGUF) get synthesized ones. So this repo's params and system are what will be served, not defaults.

This architecture gets a correct derived template. There is deliberately no template file here, because Ollama templates must be Go, not Jinja. The Hub covers that case by matching the GGUF's embedded tokenizer.chat_template against a library of known templates. For meta-models/Muse-Glimmer-30B-GGUF — same architecture, and its GGUF embeds a chat template md5-identical to this repo's chat_template.jinja (216c1d8e91a69ac1723bf341ec0d2c17) — the Hub serves this 280-byte Go template:

{{ if .System }}<|begin_of_text|><|start|>system<|message|>{{ .System }}

Reasoning strength: high.

# Valid recipients: "self", "user".<|eot|>{{ end }}{{ if .Prompt }}<|start|>user<|message|>{{ .Prompt }}<|eot|>{{ end }}<|start|>assistant to=user<|message|>{{ .Response }}<|eot|>

That is the correct ATEM protocol. Rendered with this repo's system file and a real prompt, it is byte-identical to what chat_template.jinja produces for the first 1,494 characters — every token of the system and user turns — and diverges only at the tail, where it pre-fills the full trained header <|start|>assistant to=user<|message|> (312 prompt tokens) rather than stopping at <|start|>assistant (309).

Ollama v0.34.0 ignores that Go template and renders the embedded Jinja. Measured here: building three local tags from this GGUF — one with the Hub's Go template, one with a deliberately mangled marker template, one with none — produced the same 113-token prompt and the same reply in all three cases. ollama show --template returns the ATEM Jinja template in every case. So on a current Ollama, path A renders exactly as the verified path B does: a 309-token prompt, and a reply that opens with to=user<|message|> for you to strip. On an older Ollama without a Jinja renderer the Hub's Go template would be used instead — also correct, but it pre-fills that header, so the reply will not carry it. Strip the prefix if present rather than assuming either.

The system file is load-bearing, not decoration. The same GGUF built without it drops from 113 to 58 prompt tokens and degenerates immediately, emitting stray <|start|>assistant headers instead of code. Do not delete it.

The 56 GB of safetensors do not interfere. Of 600 GGUF repos surveyed, 28 ship root-level safetensors alongside GGUFs; their Ollama manifests resolve to a GGUF and ignore the safetensors entirely. Ollama pulls 16.9 GB from this repo, never the bf16 weights.

Two things remain untested, both requiring the published repo: the pull of this repo id, and the SSH-key handshake Ollama needs for a private repo (cat ~/.ollama/id_ed25519.pubhttps://huggingface.co/settings/keys).

Building your own GGUF (optional)

Steps 0-2 below are needed only if you want a quantisation other than the shipped Q4_K_M. Steps 3-4 are the verified ollama create and ollama run transcript, and they apply unchanged to the GGUF in this repo.

Support for this architecture landed in llama.cpp in PR #26841 ("model: Muse Glimmer Support", merged 2026-08-10, merge commit 62bf73d25c) with the GGUF arch string muse-glimmer (LLM_ARCH_MUSE_GLIMMER, src/llama-arch.cpp; model implementation src/models/muse-glimmer.cpp; converter conversion/muse_glimmer.py).

0. The transformers pin in llama.cpp's requirements will break the conversion

This is the one step that fails out of the box, so do it before anything else. requirements/requirements-convert_hf_to_gguf.txt pulls in requirements-convert_legacy_llama.txt, which pins transformers==4.57.6. This repo's tokenizer_config.json declares "tokenizer_class": "TokenizersBackend", a class that only exists in transformers 5.x. With the pinned version, conversion dies while reading the vocab:

ValueError: Tokenizer class TokenizersBackend does not exist or is not currently imported

Install transformers 5.x after the requirements file so it wins:

pip install -r requirements/requirements-convert_hf_to_gguf.txt
pip install 'transformers>=5.17'      # overrides the 4.57.6 pin above

Do not work around this by editing tokenizer_config.json — the declared class is correct for the tokenizer this model ships.

Pre-flight the vocab before committing to a ~52 GB write:

python convert_hf_to_gguf.py /path/to/muse-glimmer-30b-kernelgen \
    --outfile /tmp/vocab-probe.gguf --vocab-only

1. Convert to GGUF

git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
# ... the two pip commands from step 0 ...

python convert_hf_to_gguf.py /path/to/muse-glimmer-30b-kernelgen \
    --outfile muse-glimmer-30b-kernelgen-bf16.gguf \
    --outtype bf16

Measured output: 55,725,514,560 bytes (51.9 GiB), 731 tensors. Make sure the filesystem has room for that plus the quantised copy.

You do not need a vision projector. The converter registers two classes for this architecture — MuseGlimmerModel(TextModel) and MuseGlimmerVisionModel(MmprojModel). A plain convert_hf_to_gguf.py invocation produces the text model only; the projector is a separate --mmproj run. Verified on the output above: zero mmproj/vision_tower tensors, consistent with the vision tower having been excluded from training.

Why the GGUF has 731 tensors when this repo has 627 non-vision ones

The converter is not a 1:1 repack, so don't compare the two counts directly:

  • It synthesizes attn_q_norm and attn_k_norm (length head_dim = 128) for every block to absorb qk_scale_factor, which this model applies as a scaleless RMSNorm followed by a scalar (conversion/muse_glimmer.py). That is 2 × 52 blocks = 104 tensors — exactly the 731 − 627 difference.
  • It adds 1.0 to every *layernorm.weight (zero-centred norms).
  • It un-permutes Q/K projections to match ggml's interleaved RoPE.

So GGUF tensor values are deliberately not bit-identical to the safetensors.

2. Quantize

bf16 needs ~52 GiB resident. Quantize unless you have that much VRAM:

cmake -B build && cmake --build build --config Release -j
./build/bin/llama-quantize muse-glimmer-30b-kernelgen-bf16.gguf \
    muse-glimmer-30b-kernelgen-Q4_K_M.gguf Q4_K_M

Measured on this repo's weights (Q4_K_M took 80 s on 48 threads):

Quant Size on disk BPW Status
bf16 55,725,514,560 B — 51.9 GiB 16.00 measured
Q4_K_M 16,935,295,040 B — 15.8 GiB 4.86 measured

llama-quantize reported model size = 53131.48 MiBquant size = 16138.25 MiB. Other K-quants land between these two; the two rows above are the only ones actually built and run here, so they are the only ones quoted.

For calibration, the base model card reports its own K-quants at 0.2% degradation in 32 GB of VRAM and 1.0% at 17 GB / 24 GB VRAM. Those are the base model's figures on the base model's benchmarks — not this fine-tune's, and not on this task.

3. Create the Ollama model

A ready-to-use Modelfile ships in this repo: it pins greedy decoding, an 8,192-token context to match training, the two stop tokens, and the verbatim training system prompt. Point its FROM line at the GGUF you built, then:

ollama create kernelgen-muse-glimmer -f Modelfile

Verified — ollama show then reports:

  Model
    architecture        muse-glimmer
    parameters          27.9B
    context length      131072
    embedding length    6656
    quantization        Q4_K_M

  Parameters
    num_predict    2048
    stop           "<|eot|>"
    stop           "<|end_of_text|>"
    temperature    0
    top_k          1
    num_ctx        8192

Three things that are easy to get wrong, all confirmed on this build:

  • num_ctx is load-bearing. Ollama sizes the default context from available VRAM and on this host chose default_num_ctx=262144. The Modelfile pins 8,192 to match MAX_SEQ_LEN at training time.
  • The chat template comes across intact. ollama show --template returns the ATEM Jinja template embedded in the GGUF. That template is byte-identical (md5 216c1d8e91a69ac1723bf341ec0d2c17) to llama.cpp's own bundled models/templates/muse-glimmer.jinja, and Ollama's rendering of the example below tokenised to 309 tokens — the same count the transformers tokenizer produces for the same messages.
  • ollama show lists a tools capability. That comes from the base model's ATEM template, not from this fine-tune. This adapter was trained only on single-turn kernel generation; tool calling is untrained here.
  • parameters 27.9B is the right number, and it is a useful check. The base is 29.8B including a ~1.8B vision tower (see Model details); 28.0B of text weights is what should survive, and 27.9B is what Ollama counts. A figure near 29.8B here would mean you had converted the vision tower too.

4. Run it

ollama run kernelgen-muse-glimmer

Then paste your instruction, a blank line, and the PyTorch source in a fenced code block — the same shape as the training data:

Write a complete, self-contained Triton implementation that computes the same result.

```
import torch

class RMulInt(torch.nn.Module):
    def forward(self, x):
        return 10 * x

def get_inputs():
    return [torch.rand([4, 4, 4, 4])]

def get_init_inputs():
    return [[], {}]
```

Or via the API:

curl http://localhost:11434/api/generate -d '{
  "model": "kernelgen-muse-glimmer",
  "prompt": "Write a complete, self-contained Triton implementation that computes the same result.\n\n```\nimport torch\n\nclass RMulInt(torch.nn.Module):\n    def forward(self, x):\n        return 10 * x\n\ndef get_inputs():\n    return [torch.rand([4, 4, 4, 4])]\n\ndef get_init_inputs():\n    return [[], {}]\n```",
  "options": {"temperature": 0, "num_predict": 2048, "num_ctx": 8192},
  "stream": false
}'

The prompt above is abridged for readability. The verified run used this same endpoint and model, with the full-length instruction and source of Example 2 below (309 prompt tokens), and "options": {"num_thread": 48} — every other decoding setting came from the Modelfile. Ollama's reply:

"done": true, "done_reason": "stop",
"prompt_eval_count": 309, "eval_count": 469,
"load_duration": 13.38s, "prompt_eval_duration": 3.89s, "eval_duration": 49.26s

That is 9.52 generated tokens/s on CPU alone with no GPU offload, and the response began with the to=user<|message|> header and ended cleanly at <|eot|> (done_reason: "stop").

Set num_thread if you are on a many-core shared box. Left to its own defaults, Ollama used all 192 logical cores on this host and the same request took over 17 minutes (≈0.45 tok/s) because it was contending with other tenants. Adding "num_thread": 48 brought it to the 66 s above — a >15× difference from one option. Pass it in options, or add PARAMETER num_thread 48 to the Modelfile.

Two cross-checks that the Ollama path is faithful, both measured here:

  • Ollama and llama-server produce byte-identical output from this GGUF for this prompt under greedy decoding (1,379 characters each, 469 tokens each), so Ollama's template rendering and parameter handling introduce no drift.
  • Ollama's prompt tokenised to 309 tokens, the same count transformers produces for the same system+user messages — so the Modelfile SYSTEM block plus the GGUF's embedded template reconstruct the training-time prompt.

One difference from the transformers examples further down this card: Ollama returns the raw <|message|> tag. The transformers snippet decodes with skip_special_tokens=True and so yields to=user, while Ollama's HTTP response literally begins to=user<|message|>. (On an older Ollama that uses the Hub's Go template, that header is already in the prompt and is not repeated — the loop below handles both.) Strip the whole prefix:

for prefix in (" to=user<|message|>", " to=user"):
    if text.startswith(prefix):
        text = text[len(prefix):]
        break

Stop tokens: why the Modelfile lists them explicitly

Loading the GGUF prints:

load: special_eot_id is not in special_eog_ids - the tokenizer config may be incorrect

This is cosmetic. llama.cpp inserts <|eot|> (200008) into the end-of-generation set and warns that the tokenizer config did not list it (src/llama-vocab.cpp), so generation does stop on <|eot|> by itself — the completions above ended with stop_type: eos, not on a stop string. The Modelfile's explicit stop "<|eot|>" / stop "<|end_of_text|>" lines are belt-and-braces for runtimes that don't apply that recovery.

Quantization fidelity

The same prompt (Example 2 below, greedy, temperature 0 / top_k 1) was run twice: once against the bf16 safetensors in this repo via transformers, and once against the Q4_K_M GGUF via llama-server's /completion. Both were given the byte-identical 310-token prompt.

  • Both produced valid, complete Triton that keeps the public class name and forward signature.
  • They are not token-identical: bf16 emitted 457 new tokens, Q4_K_M emitted 469, and the generated call() differs in how it obtains the CUDA device index — bf16 hard-coded device 0 (with torch.cuda._DeviceGuard(0), get_raw_stream(0)), while Q4_K_M derived it from the input tensor (with torch.cuda._DeviceGuard(arg0_1.device.index), get_raw_stream(arg0_1.device.index)). Both run; the Q4_K_M version is arguably the more portable of the two, but that is luck, not a property you can rely on.

One example is one example. The honest summary is that Q4_K_M on this model stays on-task and on-format, and changes token-level details. Combined with the fact that this model's task accuracy was never measured at any precision (see Evaluation), the operative advice stands: if a generated kernel matters, run it and check it.

Input / output examples

Example 1 — In-place ReLU (elementwise)

Validation row 343; 304 prompt tokens, 465 generated tokens.

Input (user turn, after the system prompt above):

You are given a PyTorch module together with the functions that produce its constructor arguments and its input tensors. Write a complete, self-contained Triton implementation that computes the same result.

Requirements:
- Emit one or more `@triton.jit` kernels plus the Python host code that launches them.
- Derive every compile-time constant (element counts, strides, block sizes) from the shapes implied by `get_inputs()` and `get_init_inputs()`.
- Keep the public class name and `forward` signature callable exactly as the reference is.
- Output only Python source. No explanation, no markdown fences.

```
import torch
import torch.nn.functional as F
from torch import nn


class relu(nn.Module):

    def forward(self, x):
        return F.relu(x, inplace=True)


def get_inputs():
    return [torch.rand([4, 4, 4, 4])]


def get_init_inputs():
    return [[], {}]
```

Output (verbatim, with the to=user header stripped):

import torch
import triton
import triton.language as tl
from torch._inductor.runtime.triton_heuristics import grid
from torch._C import _cuda_getCurrentRawStream as get_raw_stream
from torch._inductor.runtime import triton_helpers
from torch import nn
assert_size_stride = torch._C._dynamo.guards.assert_size_stride
empty_strided_cuda = torch._C._dynamo.guards._empty_strided_cuda


@triton.jit
def triton_poi_fused_relu_0(in_ptr0, out_ptr0, xnumel, XBLOCK: tl.constexpr):
    xnumel = 256
    xoffset = tl.program_id(0) * XBLOCK
    xindex = xoffset + tl.arange(0, XBLOCK)[:]
    xmask = xindex < xnumel
    x0 = xindex
    tmp0 = tl.load(in_ptr0 + x0, xmask)
    tmp1 = tl.full([1], 0, tl.int32)
    tmp2 = triton_helpers.maximum(tmp1, tmp0)
    tl.store(out_ptr0 + x0, tmp2, xmask)


def call(args):
    arg0_1, = args
    args.clear()
    assert_size_stride(arg0_1, (4, 4, 4, 4), (64, 16, 4, 1))
    with torch.cuda._DeviceGuard(0):
        torch.cuda.set_device(0)
        buf0 = empty_strided_cuda((4, 4, 4, 4), (64, 16, 4, 1), torch.float32)
        get_raw_stream(0)
        triton_poi_fused_relu_0[grid(256)](arg0_1, buf0, 256, XBLOCK=256,
            num_warps=4, num_stages=1)
        del arg0_1
    return buf0,


class reluNew(nn.Module):

    def forward(self, input_0):
        arg0_1 = input_0
        output = call([arg0_1])
        return output[0]

Correct elementwise ReLU, but not an exact match to the reference: the reference honours inplace=True by writing back into the input buffer, while the model allocates a fresh output buffer. The returned values agree; the aliasing semantics do not.

Example 2 — Scalar multiply via rmul

Validation row 81; 310 prompt tokens, 457 generated tokens.

Input (user turn, after the system prompt above):

You are given a PyTorch module together with the functions that produce its constructor arguments and its input tensors. Write a complete, self-contained Triton implementation that computes the same result.

Requirements:
- Emit one or more `@triton.jit` kernels plus the Python host code that launches them.
- Derive every compile-time constant (element counts, strides, block sizes) from the shapes implied by `get_inputs()` and `get_init_inputs()`.
- Keep the public class name and `forward` signature callable exactly as the reference is.
- Output only Python source. No explanation, no markdown fences.

```
import torch


class RMulInt(torch.nn.Module):

    def __init__(self):
        super(RMulInt, self).__init__()

    def forward(self, x):
        return 10 * x


def get_inputs():
    return [torch.rand([4, 4, 4, 4])]


def get_init_inputs():
    return [[], {}]
```

Output (verbatim, with the to=user header stripped):

import torch
import triton
import triton.language as tl
from torch._inductor.runtime.triton_heuristics import grid
from torch._C import _cuda_getCurrentRawStream as get_raw_stream
assert_size_stride = torch._C._dynamo.guards.assert_size_stride
empty_strided_cuda = torch._C._dynamo.guards._empty_strided_cuda


@triton.jit
def triton_poi_fused_mul_0(in_ptr0, out_ptr0, xnumel, XBLOCK: tl.constexpr):
    xnumel = 256
    xoffset = tl.program_id(0) * XBLOCK
    xindex = xoffset + tl.arange(0, XBLOCK)[:]
    xmask = xindex < xnumel
    x0 = xindex
    tmp0 = tl.load(in_ptr0 + x0, xmask)
    tmp1 = 10.0
    tmp2 = tmp0 * tmp1
    tl.store(out_ptr0 + x0, tmp2, xmask)


def call(args):
    arg0_1, = args
    args.clear()
    assert_size_stride(arg0_1, (4, 4, 4, 4), (64, 16, 4, 1))
    with torch.cuda._DeviceGuard(0):
        torch.cuda.set_device(0)
        buf0 = empty_strided_cuda((4, 4, 4, 4), (64, 16, 4, 1), torch.float32)
        get_raw_stream(0)
        triton_poi_fused_mul_0[grid(256)](arg0_1, buf0, 256, XBLOCK=256,
            num_warps=4, num_stages=1)
        del arg0_1
    return buf0,


class RMulIntNew(torch.nn.Module):

    def __init__(self):
        super(RMulIntNew, self).__init__()

    def forward(self, input_0):
        arg0_1 = input_0
        output = call([arg0_1])
        return output[0]

Byte-for-byte identical to the reference implementation.

Example 3 — Fused add + acos (libdevice)

Validation row 124; 328 prompt tokens, 494 generated tokens.

Input (user turn, after the system prompt above):

You are given a PyTorch module together with the functions that produce its constructor arguments and its input tensors. Write a complete, self-contained Triton implementation that computes the same result.

Requirements:
- Emit one or more `@triton.jit` kernels plus the Python host code that launches them.
- Derive every compile-time constant (element counts, strides, block sizes) from the shapes implied by `get_inputs()` and `get_init_inputs()`.
- Keep the public class name and `forward` signature callable exactly as the reference is.
- Output only Python source. No explanation, no markdown fences.

```
import torch
import torch.jit
import torch.onnx
import torch.nn


class SimpleACosModule(torch.nn.Module):

    def __init__(self):
        super(SimpleACosModule, self).__init__()

    def forward(self, a):
        return torch.acos(a + a)


def get_inputs():
    return [torch.rand([4, 4, 4, 4])]


def get_init_inputs():
    return [[], {}]
```

Output (verbatim, with the to=user header stripped):

import torch
import triton
import triton.language as tl
from torch._inductor.runtime.triton_heuristics import grid
from torch._C import _cuda_getCurrentRawStream as get_raw_stream
from torch._inductor.runtime.triton_helpers import libdevice
import torch.jit
import torch.onnx
import torch.nn
assert_size_stride = torch._C._dynamo.guards.assert_size_stride
empty_strided_cuda = torch._C._dynamo.guards._empty_strided_cuda


@triton.jit
def triton_poi_fused_add_acos_0(in_ptr0, out_ptr0, xnumel, XBLOCK: tl.constexpr
    ):
    xnumel = 256
    xoffset = tl.program_id(0) * XBLOCK
    xindex = xoffset + tl.arange(0, XBLOCK)[:]
    xmask = xindex < xnumel
    x0 = xindex
    tmp0 = tl.load(in_ptr0 + x0, xmask)
    tmp1 = tmp0 + tmp0
    tmp2 = libdevice.acos(tmp1)
    tl.store(out_ptr0 + x0, tmp2, xmask)


def call(args):
    arg0_1, = args
    args.clear()
    assert_size_stride(arg0_1, (4, 4, 4, 4), (64, 16, 4, 1))
    with torch.cuda._DeviceGuard(0):
        torch.cuda.set_device(0)
        buf0 = empty_strided_cuda((4, 4, 4, 4), (64, 16, 4, 1), torch.float32)
        get_raw_stream(0)
        triton_poi_fused_add_acos_0[grid(256)](arg0_1, buf0, 256, XBLOCK=256,
            num_warps=4, num_stages=1)
        del arg0_1
    return buf0,


class SimpleACosModuleNew(torch.nn.Module):

    def __init__(self):
        super(SimpleACosModuleNew, self).__init__()

    def forward(self, input_0):
        arg0_1 = input_0
        output = call([arg0_1])
        return output[0]

Semantically identical to the reference. The only differences are the kernel name's op ordering (triton_poi_fused_add_acos_0 vs the reference's triton_poi_fused_acos_add_0) and line wrapping.

What these examples do and do not show

All three produce plausible, well-formed torch._inductor-style Triton code with the right kernel structure, and two of three are semantically equivalent to the reference (one byte-identical). None was compiled or executed — no correctness claim is being made here. The ReLU case shows the failure mode to watch for: output that looks right and is subtly wrong about aliasing.

Decoding cost on CPU was 1.3 tokens/second for reference (2.6 minutes per example above). That is a CPU number on a contended box, not a GPU benchmark.

Training details

Data. 8,949 training / 367 validation samples, assembled locally.

Source Rows Handling
GPUMODE/KernelBook 6,971 Permissively licensed rows only; de-duplicated; 462 rows overlapping KernelBench dropped
GPUMODE/kernelbot-data (pmpp_v2_submissions) 1,978 Every submission re-run on an H200 under triton 3.1.0 / torch 2.5.1+cu121; kept only if it ran correctly and landed at or under the p75 wall-clock for its task

8,011 further rows were dropped outright: the histogram_v2, sort_v2, and conv2d_v2 task families are sealed out of training entirely because they are the held-out speedup benchmark. Training on the benchmark you report against is not a measurement.

Token lengths under the Muse-Glimmer tokenizer:

Split Median p95 p99 Max Fits 8,192
Train 1,780 4,982 7,724 9,813 99.3%
Validation 1,933 8,206 98.9%

Method

QLoRA: 4-bit NF4 quantized base, bf16 LoRA adapters, bf16 compute. TRL SFTTrainer, loss over the full rendered sequence. 8 x H200, torchrun --nproc_per_node 8.

Final hyperparameters

Knob Value
training_method qlora
lora_r 16
lora_alpha 32
lora_dropout 0.05
learning_rate 2e-4
lr_scheduler cosine
epochs 2
batch_size (per device) 1
grad_accum 4
effective batch 32 (1 x 4 x 8 GPUs)
warmup_ratio 0.05
weight_decay 0.01
max_seq_len 8,192
use_dora / use_rslora false / false
lora_init default
loraplus_lr_ratio 1.0 (off)
neftune_noise_alpha 0.0 (off)
use_liger_kernel / use_sample_packing false / false

Trials

training_method eval_loss Decision Train runtime
qlora 0.078885 keep — published 5,970 s

This is the published configuration, measured once. There was a single seed and no repeat run, so treat the loss as one measurement rather than a converged estimate of the method.

Observed training metrics

train_loss 0.10914156969104494
eval_loss 0.07888498902320862
train_runtime 5,860.06 s (~1 h 37 m)
train_samples_per_second 3.054
train_steps_per_second 0.096
total_flos 6.980857555916423e+18

Evaluation

eval_loss = 0.078885 on the 367-row held-out validation split.

Environmental impact

Reported rather than estimated, since the hardware is shared and per-job power was not instrumented:

Hardware 8 x NVIDIA H200
Training runtime (published trial) 5,860 s (~1.63 h)
Total across all 3 trials 19,105 s (~5.3 h)
total_flos (published trial) 6.98e+18

Carbon emitted was not measured; the grid region and PUE of the host are not known to the authors.

Framework versions

PEFT 0.18.1
TRL 1.0.0
Transformers 5.16.0.dev0 (git main)
PyTorch 2.5.1+cu121
Datasets 4.8.4
Tokenizers 0.23.1

muse_glimmer is not in any stable transformers release as of 2026-09-14. A git-main install is required to load this model.

Citation

Cite this model, the base model, and the training stack:

@misc{muse_glimmer_30b_kernelgen_2026,
  title  = {muse-glimmer-30b-kernelgen},
  author = {{SASVA AI Model Cognition Labs (MCL) Team}},
  year   = {2026},
  url    = {https://huggingface.co/SASVAAI/muse-glimmer-30b-kernelgen}
}

@misc{muse-glimmer-30b,
  title  = {Muse-Glimmer-30B},
  author = {Meta Superintelligence Lab},
  year   = {2026},
  url    = {https://huggingface.co/meta-models/Muse-Glimmer-30B}
}

@misc{trl,
  title  = {TRL: Transformer Reinforcement Learning},
  author = {von Werra, Leandro and others},
  year   = {2020},
  url    = {https://github.com/huggingface/trl}
}
Downloads last month
701
Safetensors
Model size
30B params
Tensor type
BF16
·
Inference Examples
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for SASVAAI/muse-glimmer-30b-kernelgen

Merge model
this model